読者です 読者をやめる 読者になる 読者になる

『この世界の片隅に』を観たときの頭の抽き出し整理

konosekai.jp

とりあえず、ここでは映画のレビューとか感想は書きません。
なんというかこー

と言う感じで、感想を書いて一区切り置いてしまうのがあまりに勿体ない。

ということで、感想の代わりに映画を見てたとき「そういえばあの本にこういう事を書いてたよな」と思っていたことについて、さらっと再読したメモ。目的としては「頭の抽き出し整理」というか、あの映画を受け止めたときの自分の手持ちカードを晒す的な。



「月給百円」のサラリーマン―戦前日本の「平和」な生活 (講談社現代新書)

「月給百円」のサラリーマン―戦前日本の「平和」な生活 (講談社現代新書)

冒頭の、昭和8年の広島の場面で思い出してたのがこの本。
昭和一桁時代の物価は大体今の二千分の一ぐらい(当時の1円 = 現在の2,000円)。都市部の中流層が「そこそこ暮らしていける」ぐらいの目安になる月収が大体100円程度。
ただし、中流層と言っても人口比でいうと10%ぐらいの少数派で、貧困層は子供を身売りすることも当たり前という状態(この辺は映画版で大幅カットされたエピソードの背景)。
日中戦争が始まってからはインフレが進み(そして、公定価格は抑えられたものの統計に現れない闇価格は高騰し)、戦後の物価上昇を経て最終的に「キャラメル一箱百円、靴下三足千円」な現在に至る。

それにしても、すずさんってあの時まで闇市場のお世話に成ったことが無かったんだろうか?そうだとしたら、それが一般的な話なのか特殊事例なのか、よくわからない。東京を舞台にした作品だと、もうちょっとカジュアルに闇に頼ってる気がする。


戦前戦中の主婦雑誌に掲載されていたレシピを元に戦時の食生活を描く本。
日中戦争が始まった頃は、意識高い系奥様向けに「軍艦サラダ」「飛行機メンチボール」のような手の込んだ料理が紹介されていたのに、戦争が進むにつれて「如何に米を水増しするか」という方向に成っていき、さらには配給制度が始まり、最後には配給では必須カロリーを満たせなくなり...という。
そういえば、この本だと隣組をベースにして複数の家から材料を持ち寄って共同炊事をやっていたということだけど、『この世界の片隅に』だと漫画版も映画版も共同炊事の描写は無かった気がする。
この辺の事情は都市部と地方で大分違うのかもしれない。

それにしても、男手二人が海軍関係に勤務していて(流石にお義父さんは年齢的に大丈夫だろうけど、周作さんもぎりぎりまで招集されず)、ふたりとも家から通勤可能で(週末に労働力としてあてに出来る)、さらに畑もあるという北條家って当時としては大分恵まれていた方なんじゃなかろうか。

あと、1939年の段階で米の国内消費量のうち20%が植民地からの移入米というデータも出てて、八月十五日慟哭シーンの背景になってる。


決戦下のユートピア (文春文庫)

決戦下のユートピア (文春文庫)

そいやこの本で、モンペ着用については余りのダサさに「都会の娘 vs. 田舎のおばさん」的な対立があるという話だったけど、地方都市だとこの辺の対立はあんまり無かったんだろうかと気になった。すずさんがその辺に頓着しないのは分かるけど、元モガの徑子さんはどういう思いでモンペを着てたんだろうか。


造船士官の回想〈上〉 (新戦史シリーズ)

造船士官の回想〈上〉 (新戦史シリーズ)

造船士官の回想〈下〉 (新戦史シリーズ)

造船士官の回想〈下〉 (新戦史シリーズ)

著者は戦争中に呉工廠へ赴任。大和や武蔵の修理に関わってたりする。あと、第十一海軍航空廠で航空関連の仕事もしているので、北條のお義父さんと関わりが有ってもおかしくないのな。度重なる呉空襲についての記述も有ったりと、『この世界の片隅に』と関連しそうな部分が結構ある。
あと、海軍病院で兵員が多い病棟ではレコードでアメリカの曲ばかりがかかっていたという記述も有ったりと、映画中のワンシーンを思い起こさせる。


源田の剣 改訂増補版 米軍が見た「紫電改」戦闘機隊全記録

源田の剣 改訂増補版 米軍が見た「紫電改」戦闘機隊全記録

艦載機による呉空襲について、米軍側から見た記録を中心に再現した記述あり。"色彩豊かに弾幕が張られていた"というあのシーンについての米側証言も出てる。
あと、呉上空でドッグファイトしていたシーンが有ったけれど、あのときの日本機は第343海軍航空隊 戦闘301飛行隊所属で他に該当する部隊は無いとの事*1。隊長は最近一部でものっそ有名になってる、あの菅野直大尉。
第十一海軍航空廠で紫電改を作ってたし、あの光景を見たらそりゃお義父さんもたぎるよね。



とまあ色々書いたけど、特にこの手の知識とか無くても楽しめる映画です。画面一杯に情報がつぎ込まれているものの、別にそれを全て受け止める必要は無いはずです。むしろそういう余計なモノは放り投げて、笑い、泣き、あの「日常」を過ごした人たちに思いを馳せれば良いと思います。

*1:旧版による。増補改訂版だと変わってるかもしれない

『日本・韓国・台湾は「核」を持つのか』感想

日本・韓国・台湾は「核」を持つのか?

日本・韓国・台湾は「核」を持つのか?

核実験やミサイルの発射を繰り返す北朝鮮。核を持ち強大な軍事力を背景に領土拡張をやめない中国。これらに隣接する日本、韓国、台湾が実際に「核兵器」を保有する日は来るのか? それは連鎖的な「核ドミノ」をもたらすのか?1 核開発の概況、2歴史的経緯、3開発レベルと対外関係、4核兵器保有の動機、4抑止要因などの視点から、北東アジアにおける「核」のリアルを冷静に分析。中国が暴走し、米国のアジア戦略が揺れる現在の必読書!

刺激的なタイトルとテーマではあるけれど、内容はいたって穏健。
韓国・日本・台湾(核兵器を持ちうる可能性が高い順)についてそれぞれの国情や過去の核兵器開発の経緯をまとめた上で

  • 韓国
    • 世論的には過半数が核兵器保有に賛成
    • 過去に核兵器開発を試みた歴史があるが、現在の監査体制の下ではまず秘密裏の自力開発は無理
    • 北朝鮮崩壊時に、核兵器開発インフラは米国が責任を持って破壊しないとまずい
  • 日本
    • 冷戦期から、(潜在的核兵器へ転換できるような)民間核技術や宇宙開発技術を積み上げてきている
    • また、これらの技術を自覚的に「核ヘッジング」として対米外交で使っても居る(「アジアへの介入に及び腰になるなら、民生技術を核兵器開発に転用しちゃる」的なシグナル)
    • ただ、一方で日本は核の平和利用と拡散防止の国際的な旗手でもある
    • この姿勢は一見矛盾するようだけれど米国による「(核を含む)安全保障の傘」に依存することで両立しうる
    • 実際、核兵器作ると成るとそれなりの時間はかかるし、透明性が高い社会と核兵器への反発が強い世論の中で極秘開発はほぼ無理
  • 台湾
    • 現在の監査体制の下では核兵器の極秘開発は無理
    • 仮に開発が露見した場合、米国からの(暗黙の)安全保障が切れ、かつ中国からの先制攻撃の口実も与えてしまうので誰得

という感じで、これらの国では核兵器の開発はまず無理だし、そもそもそんなことをやる必然性も薄いという感じでまとまっています。
ただ、これらの結論は前提として

  • 核兵器の極秘開発がバレたら国際的に爪弾きとなり、米も本気で制裁してくる
  • 米国が東アジアで十分な軍事力を保持し続ける
  • 米国は同盟国への軍事的義務を果たすために(必要であれば核兵器の先制使用を含む)軍事力行使を厭わない

というあたりについて、米側も同盟国側も確信していることが大前提になります。


で、ここからが感想の本題。普通だとまあ大統領が変わろうがこの辺の基本ラインが変わることは無いはずですし、この本の本文でも「アメリカはそういう役割を果たし続ける」ことが自明の理として書かれています。しかし、トランプ氏が大統領選で勝利した今、この辺の信頼が(建前的な部分ではなく本音の部分で)大きく削がれる可能性があります*1

著者による日本語刊行版への序文でこの辺の発言に触れられていますが、短くまとめると「対立候補クリントン氏だから安心」て感じでトランプ政権の誕生については想定外の様子。なにせ「アメリカが同盟国への軍事的義務を果たさない可能性と、その場合に想定される情勢」について、本書ではほぼ触れられてません。


ほんの数年前までは自明の理だったことがひっくり返るあたり、百年後ぐらいに歴史の教科書で読むとしたら凄い面白い時代だろうなと。
でも、そんな時代に生きたくないよぬ

*1:実際にトランプ政権が誕生した時、この辺の信頼回復に力を注ぐかもしれないし、逆に国際的な安全保障とかかなぐり捨てて米大陸に引きこもるかもしれない。ただ、現時点でどちらに転ぶのか、あるいは他の方向へ進むのか断言できる人は多分居ない

JMeter WebDriver Plugin を使ってみた

Java JMeter

はじめに

http://jmeter.apache.org/index.html

Apache JMeterは主にWebアプリの負荷テストで使用されるツールです。
基本的にはシナリオにしたがってリクエストを投げて、想定どおりのレスポンスが戻るまでの時間を測定し、集計するというツールですが、ユーザーのインタラクティブな操作に対応したテストを行うのは苦手です。例えば、「ユーザーがWebアプリ上である操作を行った時、裏で多数の非同期通信が行われた結果がUI上に反映されるまでの時間を測定する」といったシナリオを書くのは結構面倒なのです。

そこで、JMeterのシナリオ上からブラウザを Selenium WebDriverを通じて呼び出してしまえというWebDriverプラグインの出番になります。

jmeter-plugins.org

JMeterシナリオ上でブラウザへの操作を記述し、リクエストはJMeterではなくあくまでブラウザから行い、レスポンス(とDOMへの反映)もブラウザが受け取ります。ブラウザを起動する必要が有るため、例えば大規模ユーザの同時アクセスを想定しているような、JMeterが得意な負荷テストには向きません。しかし、ブラウザを使用することで、ユーザの操作に近い形でのテストシナリオを記述する事が可能になります。

jMeterとWebDriver APIそれぞれについてある程度知識のある人向けに、JMeter WebDriver Plugin を使って Mozilla Firefox によるテストシナリオを作成してみます。

インストール方法

1. plugins-managerの導入

jmeter-plugins.org

から plugins-managerのjarファイルを入手し、以下のフォルダへコピーします。

${JMeterインストールフォルダ}/lib/ext

現時点ではjmeter-plugins-manager-0.10.jarです。

2. WebDriver Pluginのインストール

plugins-managerの導入後にJMeterを起動すると、メニューの [オプション]配下に[Plugins Manager]が追加されるので、クリックします。
Plugins Mnagerダイアログが表示されるので、[Available Plugins]タブを選択し、インストール候補プラグイン一覧から[Selenium WebDriver Support]にチェックを入れ、「Apply Changes and Restart JMeter」ボタンをクリックします

現時点では

${JMeterインストールフォルダ}/lib/ext

jmeter-plugins-webdriver-1.4.0.jarがダウンロードされ、さらにlibフォルダに関連jarファイル群がダウンロードされます。

3. selenium-firefox-driverのjarファイルを更新

jmeter-plugins-manager v1.10, jmeter-plugins-webdriver v1.4.0の組み合わせでは以下の手順が必要です)

いったんJMeterを停止した後、

${JMeterインストールフォルダ}/lib

フォルダに"selenium-firefox-driver-2.xx.x.jar"(xは任意のバージョン番号)が存在する事を確認します。そして

Maven Repository: org.seleniumhq.selenium » selenium-firefox-driver


にv2.xx.x系のより新しいバージョンのjarファイルが存在するようであれば、jarファイルを入手して入れ替えます。Selenium WebDriverは、ブラウザが更新されると動かなくなる場合が多々有ります。そのつど上記jarをより新しいバージョンに入れ替えてください。

4. firefox 停止時のエラーを対策

jmeter-plugins-manager v1.10, jmeter-plugins-webdriver v1.4.0の組み合わせでは以下の手順が必要です)

ここまでJMeterをセットアップした状態で、WebDriver Pluginを使ってFirefoxを起動すると、シナリオ終了時に以下のような例外が出力されます。

2016/09/12 20:47:28 ERROR - jmeter.JMeter: Uncaught exception:  java.lang.NoClassDefFoundError: com/sun/jna/platform/win32/Kernel32
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
	at java.security.AccessController.doPrivileged(Native Method)

この問題に対応するため、

${JMeterインストールフォルダ}/lib

へplatform-3.5.1.jar およびjna-4.2.1.jarを導入し、JMeterを再起動します。
詳細は以下のサイトを参照。

hellotestworld.com

JMeterシナリオの作成

ここまでセットアップした後、「設定エレメント」として各ブラウザに対応するWebDriver設定が追加されます。この設定エレメントをシナリオへ加えることで、以降はWebDriver Pluginでは該当ブラウザが使用されるようになります。

f:id:ka-ka_xyz:20160913001813p:plain


また、「サンプラー」としてWebDriver Samplerが追加されます。

f:id:ka-ka_xyz:20160913001825p:plain

このSamplerにはスクリプトが記述できます。デフォルトではjavascript

WDS.sampleResult.sampleStart()
WDS.browser.get('http://jmeter-plugins.org')
WDS.sampleResult.sampleEnd()

のようなテンプレが入力されています。
このテンプレでは、測定開始後にjmeter-plugins.orgへアクセスし、測定を完了するという処理を行っています。

新規にシナリオを作成し、スレッドグループ配下にWebDriver設定、WebDriverサンプラー、リスナー「結果を表で表示」を追加してシナリオを保存します。この状態でシナリオを実行するとブラウザが立ち上がり、jmeter-plugins.orgへアクセスした後にブラウザウィンドウが閉じられます。実行結果はリスナーに出力されます。


WebDriverサンプラーの詳細については以下を参照。

www.blazemeter.com
www.blazemeter.com

複数のWebDriverサンプラー間でコードを再利用

各WebDriverサンプラーjavascript(あるいは選択可能な他のスクリプト)でコードを書くことが出来ますが、変数のスコープは各サンプラーの中に限定されます。ただ、それでは不便なので、サンプラー間でコードを共有してみます*1

シナリオに「設定エレメント」-「ユーザー定義変数」を追加し、ユーザー定義変数"lib"を定義します。
そして、"lib"を選択した状態で"Detail"ボタンをクリックすると、ユーザー定義変数を複数行編集出来るようになります。

サンプルとして、以下の内容を入力します。

var mylib = mylib || {};

mylib.pkg = JavaImporter(org.openqa.selenium);
mylib.conditions = org.openqa.selenium.support.ui.ExpectedConditions;
mylib.wait = new org.openqa.selenium.support.ui.WebDriverWait(WDS.browser, 10);
mylib.vars = org.apache.jmeter.threads.JMeterContextService.getContext().getVariables();

mylib.google = (function() {
  var googleUrl = 'https://www.google.co.jp';

  var access = function() {
    WDS.browser.get(googleUrl);
  };

  var search = function(keyword) {
  	var inputQuery = 'input#lst-ib';
  	mylib.wait.until(mylib.conditions.presenceOfElementLocated(mylib.pkg.By.cssSelector(inputQuery)));
    var inputElem = WDS.browser.findElement(mylib.pkg.By.cssSelector(inputQuery));
    inputElem.sendKeys(mylib.pkg.Keys.chord(mylib.pkg.Keys.CONTROL, 'a'), keyword, mylib.pkg.Keys.ENTER);
  };

  var waitForResultsShown = function() {
    var resultListQuery = '#search';
    mylib.wait.until(mylib.conditions.presenceOfElementLocated(mylib.pkg.By.cssSelector(resultListQuery)));
  };

  return {
    access: access,
    search: search,
    waitForResultsShown: waitForResultsShown
  };
})();

名前空間 mylib に、googleの検索フォームへの入力を行う関数やユーテリティ類を定義しています。
そして、サンプラー側で以下のスクリプトを記述します。


サンプラー1

//load mylib
eval(org.apache.jmeter.threads.JMeterContextService.getContext().getVariables().get('lib'));

WDS.sampleResult.sampleStart();
mylib.google.access();
mylib.google.search('jMeter');
mylib.google.waitForResultsShown();


WDS.sampleResult.sampleEnd();

サンプラー2

//load mylib
eval(org.apache.jmeter.threads.JMeterContextService.getContext().getVariables().get('lib'));

WDS.sampleResult.sampleStart();
mylib.google.access();
mylib.google.search('Selenium WebDriver');
mylib.google.waitForResultsShown();

WDS.sampleResult.sampleEnd();

ユーザー定義変数"lib"を文字列として読み出し、evalすることで変数"lib"中に書かれた"mylib"定義が読み出されます。

eval を使っている事に嫌悪感があるかもしれませんが、JMeter WebDriver Pluginの制約上しょうが無いかなと。"Eval is Evil"は原則として正しいとは思いますが、今回は外部から入力された文字列をevalしている訳ではなく、あくまでJMeterのシナリオで変数として定義された文字列をしようしているので、危険は無いはず(おねがいみのがして)。

f:id:ka-ka_xyz:20160913004600p:plain

このシナリオを実行すると

1. google.co.jpへアクセス
2. キーワード"jMeter"で検索
3. 検索結果が表示されるまで待つ
4. google.co.jpへアクセス
5. キーワード"Selenium WebDriver"で検索
6. 検索結果が表示されるまで待つ
7. ブラウザを閉じる

というシナリオが実行されます。


jmxファイルの内容は以下のとおり

<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="2.9" jmeter="3.0 r1743807">
  <hashTree>
    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="テスト計画" enabled="true">
      <stringProp name="TestPlan.comments"></stringProp>
      <boolProp name="TestPlan.functional_mode">false</boolProp>
      <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
      <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="ユーザー定義変数" enabled="true">
        <collectionProp name="Arguments.arguments"/>
      </elementProp>
      <stringProp name="TestPlan.user_define_classpath"></stringProp>
    </TestPlan>
    <hashTree>
      <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="スレッドグループ" enabled="true">
        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="ループコントローラ" enabled="true">
          <boolProp name="LoopController.continue_forever">false</boolProp>
          <stringProp name="LoopController.loops">1</stringProp>
        </elementProp>
        <stringProp name="ThreadGroup.num_threads">1</stringProp>
        <stringProp name="ThreadGroup.ramp_time">1</stringProp>
        <longProp name="ThreadGroup.start_time">1473680458000</longProp>
        <longProp name="ThreadGroup.end_time">1473680458000</longProp>
        <boolProp name="ThreadGroup.scheduler">false</boolProp>
        <stringProp name="ThreadGroup.duration"></stringProp>
        <stringProp name="ThreadGroup.delay"></stringProp>
      </ThreadGroup>
      <hashTree>
        <com.googlecode.jmeter.plugins.webdriver.config.FirefoxDriverConfig guiclass="com.googlecode.jmeter.plugins.webdriver.config.gui.FirefoxDriverConfigGui" testclass="com.googlecode.jmeter.plugins.webdriver.config.FirefoxDriverConfig" testname="jp@gc - Firefox Driver Config" enabled="true">
          <stringProp name="WebDriverConfig.proxy_type">SYSTEM</stringProp>
          <stringProp name="WebDriverConfig.proxy_pac_url"></stringProp>
          <stringProp name="WebDriverConfig.http_host"></stringProp>
          <intProp name="WebDriverConfig.http_port">8080</intProp>
          <boolProp name="WebDriverConfig.use_http_for_all_protocols">true</boolProp>
          <stringProp name="WebDriverConfig.https_host"></stringProp>
          <intProp name="WebDriverConfig.https_port">8080</intProp>
          <stringProp name="WebDriverConfig.ftp_host"></stringProp>
          <intProp name="WebDriverConfig.ftp_port">8080</intProp>
          <stringProp name="WebDriverConfig.socks_host"></stringProp>
          <intProp name="WebDriverConfig.socks_port">8080</intProp>
          <stringProp name="WebDriverConfig.no_proxy">localhost</stringProp>
          <boolProp name="WebDriverConfig.maximize_browser">true</boolProp>
          <boolProp name="WebDriverConfig.reset_per_iteration">false</boolProp>
          <boolProp name="WebDriverConfig.dev_mode">false</boolProp>
          <boolProp name="FirefoxDriverConfig.general.useragent.override.enabled">false</boolProp>
          <boolProp name="FirefoxDriverConfig.network.negotiate-auth.allow-insecure-ntlm-v1">false</boolProp>
          <collectionProp name="FirefoxDriverConfig.general.extensions"/>
          <collectionProp name="FirefoxDriverConfig.general.preferences"/>
        </com.googlecode.jmeter.plugins.webdriver.config.FirefoxDriverConfig>
        <hashTree/>
        <Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="ユーザー定義変数" enabled="true">
          <collectionProp name="Arguments.arguments">
            <elementProp name="lib" elementType="Argument">
              <stringProp name="Argument.name">lib</stringProp>
              <stringProp name="Argument.value">var mylib = mylib || {};

mylib.pkg = JavaImporter(org.openqa.selenium);
mylib.conditions = org.openqa.selenium.support.ui.ExpectedConditions;
mylib.wait = new org.openqa.selenium.support.ui.WebDriverWait(WDS.browser, 10);
mylib.vars = org.apache.jmeter.threads.JMeterContextService.getContext().getVariables();

mylib.google = (function() {
  var googleUrl = &apos;https://www.google.co.jp&apos;;

  var access = function() {
    WDS.browser.get(googleUrl);
  };

  var search = function(keyword) {
  	var inputQuery = &apos;input#lst-ib&apos;;
  	mylib.wait.until(mylib.conditions.presenceOfElementLocated(mylib.pkg.By.cssSelector(inputQuery)));
    var inputElem = WDS.browser.findElement(mylib.pkg.By.cssSelector(inputQuery));
    inputElem.sendKeys(mylib.pkg.Keys.chord(mylib.pkg.Keys.CONTROL, &apos;a&apos;), keyword, mylib.pkg.Keys.ENTER);
  };

  var waitForResultsShown = function() {
    var resultListQuery = &apos;#search&apos;;
    mylib.wait.until(mylib.conditions.presenceOfElementLocated(mylib.pkg.By.cssSelector(resultListQuery)));
  };

  return {
    access: access,
    search: search,
    waitForResultsShown: waitForResultsShown
  };
})();
</stringProp>
              <stringProp name="Argument.metadata">=</stringProp>
            </elementProp>
          </collectionProp>
        </Arguments>
        <hashTree/>
        <com.googlecode.jmeter.plugins.webdriver.sampler.WebDriverSampler guiclass="com.googlecode.jmeter.plugins.webdriver.sampler.gui.WebDriverSamplerGui" testclass="com.googlecode.jmeter.plugins.webdriver.sampler.WebDriverSampler" testname="WebDriver Sampler1" enabled="true">
          <stringProp name="WebDriverSampler.script">//load mylib
eval(org.apache.jmeter.threads.JMeterContextService.getContext().getVariables().get(&apos;lib&apos;));

WDS.sampleResult.sampleStart();
mylib.google.access();
mylib.google.search(&apos;jMeter&apos;);
mylib.google.waitForResultsShown();


WDS.sampleResult.sampleEnd();</stringProp>
          <stringProp name="WebDriverSampler.parameters"></stringProp>
          <stringProp name="WebDriverSampler.language">javascript</stringProp>
        </com.googlecode.jmeter.plugins.webdriver.sampler.WebDriverSampler>
        <hashTree/>
        <com.googlecode.jmeter.plugins.webdriver.sampler.WebDriverSampler guiclass="com.googlecode.jmeter.plugins.webdriver.sampler.gui.WebDriverSamplerGui" testclass="com.googlecode.jmeter.plugins.webdriver.sampler.WebDriverSampler" testname="WebDriver Sampler2" enabled="true">
          <stringProp name="WebDriverSampler.script">//load mylib
eval(org.apache.jmeter.threads.JMeterContextService.getContext().getVariables().get(&apos;lib&apos;));

WDS.sampleResult.sampleStart();
mylib.google.access();
mylib.google.search(&apos;Selenium WebDriver&apos;);
mylib.google.waitForResultsShown();

WDS.sampleResult.sampleEnd();
</stringProp>
          <stringProp name="WebDriverSampler.parameters"></stringProp>
          <stringProp name="WebDriverSampler.language">javascript</stringProp>
        </com.googlecode.jmeter.plugins.webdriver.sampler.WebDriverSampler>
        <hashTree/>
        <ResultCollector guiclass="TableVisualizer" testclass="ResultCollector" testname="結果を表で表示" enabled="true">
          <boolProp name="ResultCollector.error_logging">false</boolProp>
          <objProp>
            <name>saveConfig</name>
            <value class="SampleSaveConfiguration">
              <time>true</time>
              <latency>true</latency>
              <timestamp>true</timestamp>
              <success>true</success>
              <label>true</label>
              <code>true</code>
              <message>true</message>
              <threadName>true</threadName>
              <dataType>true</dataType>
              <encoding>false</encoding>
              <assertions>true</assertions>
              <subresults>true</subresults>
              <responseData>false</responseData>
              <samplerData>false</samplerData>
              <xml>false</xml>
              <fieldNames>true</fieldNames>
              <responseHeaders>false</responseHeaders>
              <requestHeaders>false</requestHeaders>
              <responseDataOnError>false</responseDataOnError>
              <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
              <assertionsResultsToSave>0</assertionsResultsToSave>
              <bytes>true</bytes>
              <threadCounts>true</threadCounts>
              <idleTime>true</idleTime>
            </value>
          </objProp>
          <stringProp name="filename"></stringProp>
        </ResultCollector>
        <hashTree/>
      </hashTree>
    </hashTree>
  </hashTree>
</jmeterTestPlan>

*1:ただし、今回紹介する方法だと共有できるのはあくまでコードだけで、状態は共有されないので注意

益川敏英『科学者は戦争で何をしたか』感想


正直な所、「微妙だ」という感想はあんまり力を入れて書きたくない。ただ、


を読んで、絶賛だけで終わるのはちょい違う気がするなあと思うのでちょっとネガティブな感想をまとめておきます。
この本を読んでいて一番引っかかったのは、科学者の戦争協力についてのこの文章

私がまだ学生だった頃、量子電磁力学の分野でノーベル賞を受賞した朝永振一郎博士が戦時下に書かれた論文を読んで、いたく感銘を受けたことがあります。朝永先生は戦時中、電波兵器の研究に動員されていました。「私はそんな研究に加担したくない」などと、戦時下での動員に抵抗すれば、たちまち非国民として投獄されてしまいます。
朝永先生も強制的にそうした研究に従事させられたわけですが、私は先生の論文を読んでいて、はたと膝を叩きたい思いに駆られました。量子力学を知っていればわりと簡単に見抜けることなのですが、電波の出力の関係を解析する部分を、限りなく一般的なところでまとめ、核心部分をうまくごまかしていたのです

以下、この文章についてTwitterでつぶやいていた感想のまとめ・補足



第二次大戦中の日本だと、自分の親族や隣近所の顔見知りな人たちが徴兵され、「敵」に殺されて死亡通知すら戻ってこないのが当たり前な状況でした。さらに1944年以降だと戦争に直接かかわらない市民が戦略爆撃で殺されていた訳です。そういう状況下で、本書の表現を借りれば"科学者である前に人間として"の観点から「自分の協力によって顔見知りの死や同胞の死を少しでも減らせるかもしれない」という発想が出て来るのはヒューマニストとして極自然なものではないでしょうか。
仮に上で引用したエピソードが事実であり、実際にサボタージュが行われていたとしたら、それはすさまじい苦悩の末の判断だったと思います。しかし………本書ではそのような苦悩が有ったのではないかということに触れられず、単純に素晴らしいサボタージュであり「本来の科学者の知恵」であると絶賛されています。


この本で一番危なさを感じるのはこの辺の話で、「自分の戦争協力によって顔見知りの死や同胞の死を少しでも減らせるかもしれない」という状況に追い込まれるかもしれないという可能性を考えていないように見えるところです。世論や状況が変わり、民間人の犠牲者が出た時には真っ先に戦争協力するんじゃないか的な気がします。それが良い・悪いという判断についてはここでは置いておくとして。


ファインマンがロスアラモスでの原爆開発に関わっていたことは本人が自伝で(物凄いノリノリに)書いていて有名ですが、彼も別に狂信的な国粋主義者でも無い訳で、戦時の高揚ってそういうものだと思うのです。ただ、この本では愛国心の甘美さとか戦時の高揚感、周りみんなが傷つく中で戦争に協力しないことへの罪悪感といったあたりのことについてはほぼ無視されていて危うげな気がします。

あー、あと蛇足ですがフリッツ・ハーバーが毒ガス開発に邁進した盲目的愛国者としてやり玉に上げられているあたりは

という背景について無視されてるのもなんだかなーという気がします。この辺は

毒ガス開発の父ハーバー 愛国心を裏切られた科学者 (朝日選書 834)

毒ガス開発の父ハーバー 愛国心を裏切られた科学者 (朝日選書 834)

に詳しいのでお勧め。

『撤退するアメリカと「無秩序」の世紀』についてメモ

米大統領選の大荒れ模様を見てて思い出したので軽くメモ。

撤退するアメリカと「無秩序」の世紀ーーそして世界の警察はいなくなった

撤退するアメリカと「無秩序」の世紀ーーそして世界の警察はいなくなった


まあ要約するなら「アメリカは"世界の警察"を捨てて内向き路線になりつつあるけれど、引きこもっても問題は解決しないししっぺ返しを食らうだけなので積極介入路線に戻ろうぜ」という本。で、何が気になったかというと、アメリカで中流層がどんどん貧しくなりつつあるから外征やめて引きこもろうという主張に対して

「高等教育のレベルは高いし、イノベイティブな起業家も一杯いるから大丈夫」

程度の軽い切り返しだけで終わらせている所。
例えば『誰が中流を殺すのか アメリカが第三世界に堕ちる日』に描かれているような、中流層が感じている不安の厳しさとの落差が気になってた。

誰が中流を殺すのか アメリカが第三世界に堕ちる日

誰が中流を殺すのか アメリカが第三世界に堕ちる日

なんというか、ビッグイシューを語る上でそんなの気にしないで問題無いという意識が透けて見えるというか、国際問題を語る上で「追い詰められた中流層」の話は一種のタブーになってるんじゃないかとも思うぐらいあっけらかんとした扱いで、最初に『撤退するアメリカと「無秩序」の世紀』を読んだ時には強烈な違和感があった。

で、米大統領選の大荒れって結局はこの辺の話になって、国内問題から目をそむけてきたエスタブリッシュメント層の傲慢さへの反発については色々と分析記事が出てるけれど、確かに自分が読んできた本を見てもそんな感じがするよなあというメモ。

現在中国では「隗より始めよ」の故事に"まず言い出しっぺが率先して実行しろ"というニュアンスは無いんじゃないかな?という話

自己まとめ。なんとなく気になったのでざっくり調べてみた。




「まず隗より始めよ」の元になったエピソード
manapedia.jp

は中国では"千金买骨"(骨でも大金で買う)として知られており
baike.baidu.com

その意味するところは

道理

这个故事告诉我们,要招聘人才,不仅仅要放下架子,更要有诚心,要拿出实际行动。郭隗的聪明睿智令人佩服,他的勇于自荐,自我推销的方式也很有艺术性。
现用来比喻渴望求得贤才。

とされており、Excite翻訳してみると

道理

このストーリは私達に教えて、人材を招聘して、棚をおろすだけではなくて、更に真心があって、実際行動を取り出します。郭と隗の賢い英知は人を感心させて、彼のは勇敢に自薦して、自ら売りさばく方法もとても芸術性があります。
現在比喩が賢才を求めるのを渇望するのに用います。

となる。要は「人材募集方法すげー、セルフブランディングすげー」というサクセス・ストーリーとして、そして「人材を大切にしよう」と言う意味で受け取られており、現在は「才能のある人を求めるならこういう方法を取るべきだ」という比喩として使われているとのこと。
まあ、あくまで「ソースは百度百科(キリッ」だし自動翻訳とあやふやな漢文理解だけなので断定出来ないんだけれど、この故事について"まず言い出しっぺが率先して実行しろ"というニュアンスは主流では無さそうということは分かる。


同じ古典をベースにしていてここまで解釈が違うというのは面白いし、「一見同じ古典文化を共有しているように見えるけど解釈がだいぶ違っていて、相互に誤解しっぱなし」という話は他にも結構有りそう。

P.W.シンガー 、オーガスト・コール 『ゴースト・フリート』感想

『戦争請負会社』『ロボット兵士の戦争』『子ども兵の戦争』といった一連のノンフィクションで、冷戦期の「戦争」観が覆りつつある状況を描いてミリヲタの話題をさらったP.W.シンガー。
そのシンガーが手がけた近未来米中仮想戦記ということで話題になっていた『ゴースト・フリート』が遂に翻訳されたので紹介。


中国軍を駆逐せよ!  ゴースト・フリート出撃す(上) (二見文庫 ザ・ミステリ・コレクション)

中国軍を駆逐せよ! ゴースト・フリート出撃す(上) (二見文庫 ザ・ミステリ・コレクション)

中国軍を駆逐せよ!  ゴースト・フリート出撃す(下) (二見文庫 ザ・ミステリ・コレクション)

中国軍を駆逐せよ! ゴースト・フリート出撃す(下) (二見文庫 ザ・ミステリ・コレクション)


amazonあらすじ。

2026年、中国が太平洋支配に動き、ハワイ制圧!
ロシアと同盟を組んで、太平洋制圧に挑む中国。
嘉手納基地急襲、国防総省サイバー攻撃を経て、オアフ島に上陸!

共産党支配からより少数独裁的な「董事会」体制に変わった中国は、2026年、マリアナ海溝近辺でガス田を発見、太平洋支配へと動きだした。
密かに同盟を結ぶロシアが嘉手納基地を急襲したのに続いて、中国はパナマ運河を通行不能にし、真珠湾で米軍艦船を爆破、
太平洋艦隊にも大打撃を与え、オアフ島に上陸してハワイを統治下に置くことに──。
中国のサイバー攻撃によりハイテク機器が使えないアメリカは、ハッキングの影響を受けない、現役を退いた旧い艦艇からなる「幽霊艦隊(ゴースト・フリート)」で
ハワイ奪還を目指すが──。
原題:Ghost Fleet

以下、ネタバレ

続きを読む