IT ニュース&コラム 2017/ 8/28 通巻745号 技術版 ソフトウェアデザイン館 Sage Plaisir 21  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ■■ 変数の展開を遅延評価する vbslib の LazyDictionaryClass ■■ vbslib の LazyDictionaryClass は、${ } 形式の文字列変数を遅延評価する辞書です。 遅延評価をすると、変数に値を代入する順序に依存しなくなります。 vbslib は、以下からダウンロードできます。 Windows 用です。 http://vbslib.osdn.jp/ http://www.sage-p.com/vbslib/vbslib.htm https://github.com/TsNeko/vbslib 遅延評価を説明する前に変数の基本をおさらいしましょう。 スクリプトにおいて、変数は、ファイルやフォルダーのパス(アドレス)の一部 に使うことが多いです。 変数は値に展開されます(後記サンプルを参照)。 Linux の $HOME や Windows の %USERPROFILE% などは環境変数という変数です。 Makefile や開発環境では、${HOME} のように ${ } で囲むことが多いです。 フォルダーのパス(または、その一部)に変数を使うと、フォルダーを置く場所が 変わったとしても、変数を展開すれば、その中にあるファイルやフォルダーの パスが修正されます。 たとえば、1台の PC に Aさんと Bさんの 2つのアカウントを作っているとき、 Aさんのデスクトップがあるパスと Bさんのデスクトップがあるパスは異なり ますが、環境変数を使えば(展開する前は)同じになります。   ・Aさんのデスクトップのパス: C:\Users\A\Desktop   ・Bさんのデスクトップのパス: C:\Users\B\Desktop   ・変数を使ったデスクトップのパス: %USERPROFILE%\Desktop   ・Aさんの %USERPROFILE% 変数の値: C:\Users\A   ・Bさんの %USERPROFILE% 変数の値: C:\Users\B シェルやバッチファイルでは、自動的に環境変数を自動的に値に変換しますが、 それ以外では変数を値に展開する関数を呼び出す必要があります。 vbslib の LazyDictionaryClass は、変数名(${ }形式)を辞書のキーに、 変数の値を辞書の値に指定することで、遅延評価ができるようになります。 サンプル: Set g = new LazyDictionaryClass g("${RootPath}") = "C:\Folder${Target}" '// 変数 ${RootPath} に値を設定 g("${Target}") = "A" '// 変数 ${Target} に値を設定 Assert g("${RootPath}") = "C:\FolderA" '// 変数 ${RootPath} を参照 上記のコードは文法的には、VBScript の WSH で初めから使える辞書と同じです。 辞書の文法についての詳細を知りたいときは、VBScript Scripting.Dictionary をネットで検索してください。 バッチファイルやシェルスクリプトは、遅延評価ではなく毎行で評価する(先行評価 ・正格評価である)ため、${Target} の代入を先にするよう順序を変更しなければ 期待した結果が得られません。 WSH で初めから使える辞書も先行評価なので、 順序を変更しなければなりません。 ちなみに先行評価より正格評価が正式のように ネットで書かれていますが、わざわざ読みが正確評価や性格評価と間違えそうなほうを 選ぶ意味が分かりませんし、eager evaluation の eager に正格の意味はなさそうです。 Set g = CreateObject( "Scripting.Dictionary" ) g("${Target}") = "A" g("${RootPath}") = "C:\Folder"+ g("${Target}") Assert g("${RootPath}") = "C:\FolderA" (ただし、上記の ${RootPath} 変数への代入の行は、VBScript が自動的に評価しない ことに対応するコードと、一部を評価することができないことに対応するコードも 含んでいます。) 遅延評価があれば、${RootPath} 変数への代入と ${Target} 変数への代入の順序を 入れ替えても、期待した結果が得られます。 Set g = new LazyDictionaryClass g("${Target}") = "A" g("${RootPath}") = "C:\Folder${Target}" Assert g("${RootPath}") = "C:\FolderA" 上記のコードは、最後の行で ${RootPath} を展開し、その結果に変数 ${Target} があるので更に展開して、最終的に C:\FolderA という値になります。 評価するタイミングは、辞書の値を参照するときです。 遅延評価するコードでは 評価するタイミングがいつであるかを踏まえることが挙動を理解するのに重要です。 しかし、ネットで遅延評価を検索しても関数型言語の遅延評価の説明ばかりで、 その関数型言語での評価(計算・サンク)のタイミングは、予想できないという 大きな欠点が明らかになっています。 また、挙動が理解できても期待する動作が得られなかったとき(デバッグするとき) は、変数に代入する値や展開した値を1つずつ確認しなければ解決することは 難しいです。 そこで、vbslib の LazyDictionaryClass では、 g.DebugMode = True をコードに追加することで、次のように echo 出力から確認することができます。 A C:\Folder${Target} C:\Folder${Target} C:\FolderA なお、LazyDictionaryClass の遅延評価は、文字列の展開しかサポートしていませんが、 一般に「遅延評価」という用語には、式の展開やコードの実行での遅延も含まれます。 この遅延評価という仕組みは、XML などのデータ構造に変数を使うときに必須となる 機能です。 次回は、LazyDictionaryClass を使うことで簡単に、変数が使える XML に対応する方法を説明します。 参考: https://ja.wikipedia.org/wiki/遅延評価 http://marycore.jp/prog/cpp/cpp-lazy-evaluation-and-partial-function-application/ ■■ 注目ニュース 一覧 ■■ ◇ ネットワーク障害 グーグルが設定誤りで謝罪。 http://www3.nhk.or.jp/news/html/20170827/k10011114211000.html … ネットワークの設定の誤りというが、他社はそんなミスをしていない。 ◇ 小学校の先生がプログラミングを体験。 必修化に向けて横浜市。 https://japan.cnet.com/article/35106069/ … 理数系の勉強と絡めると相乗効果が期待できる。 ◇ アプリごとに音量調節するUSBボリューム PCPanel。 出力先の選択もワンタッチ。 https://japan.cnet.com/article/35106045/ … Windows の音声ミキサーを使っていないなら不要かも。 ◇ 暗号通貨プラットフォーム Enigma にハッキング。 50万ドル被害か。 https://japan.cnet.com/article/35106164/ … 電子通貨というより、Enigma のドメインがハッキングされた。 ◇ Windows 10 Pro for Workstations は何がスゴイのか。 http://www.itmedia.co.jp/pcuser/articles/1708/22/news069.html … プロセッサーのソケットが 4つ、メモリーが 6TB まで対応。 ◇ ソニー、ディープラーニングの開発環境 Neural Network Console を公開。 https://japan.cnet.com/article/35105937/ … まだ AI はオープンソースで普及を目指す段階。 ■■ ソフトウェアデザイン館 Sage Plaisir 21 ■■ ホームページ >>> http://www.sage-p.com/ メルマガ >>> http://www.mag2.com/m/0000083983.html ブログ >>> http://blog.livedoor.jp/sage_p/ ツイッター >>> http://twitter.com/Ts_Neko ダウンロード >>> http://www.sage-p.com/freesoft.htm サポート掲示板 >>> http://www.sage-p.com/kg_ban09/z6037C8.cgi 東日本大震災 >>> http://www.sage-p.com/saigai.html メール >>> ts-neko◇sage-p.com ←◇を@に変えてください 緊急メールは件名に「うどんメール」を付けてください。 このメルマガの登録・解除 - http://www.mag2.com/m/0000083983.htm