Behind the Code - Wolfram|Alpha for Terminal



  Wolfram|Alpha for Terminal(WA4T)を使えば,Mac OS X上のターミナルからWolfram|Alphaへアクセス出来る. Wolfram|Alphaにはクエリを投げるとその結果をXMLとして返すAPIが備わっているので,Macに標準で付属されていてXMLを簡単に扱えるRubyを開発言語として選んだ. 'readline'をrequireすると,次のコードによってインタプリタのような操作感を実現出来る.
query = Readline::readline("[#{count}] = ", true)
readlineメソッドの引数にある文字列"[#{count}] = "が表示された後に,ユーザは文字列を入力することが出来るようになる. この時カーソルキーの上下にて履歴を辿ることが出来る. Enterキーを入力すると,入力された文字列を改行抜きでqueryに代入する. query(クエリ)はHTTP通信によりWolfram|Alphaへと送信されるので,適切なエンコードを施す必要がある. 具体的には特殊文字の置換と%エンコードである. Wolfram|AlphaではMathematicaの流れを汲んで,例えばシングルクオートは"\\[OpenCurlyQuote]"とも表現出来るようになっている. Rubyが特殊文字として認識するバックスラッシュ,バッククオート,ダブルクオート,シングルクオートの4種を次のコードにて無害な表現へと置換した.
文字列.gsub(置換する文字列, 置換後の文字列)
query.gsub("\\", "\\[Backslash]")
query.gsub("\`", "\\[RawBackquote]")
query.gsub("\"", "\\[RawDoubleQuote]")
query.gsub("\'", "\\[OpenCurlyQuote]")
クエリを参照している他の変数を考慮して破壊的メソッド(!付きメソッド)の使用は避けた. AppIDとqueryを得られれば,curlコマンドを用いて"input=query&appid=AppID&format=plaintext&reinterpret=true"なるパラメタをHTTPのPOSTメソッドにて"http://api.wolframalpha.com/v2/query"へ送信すれば,クエリに応じた返答をXMLとして受信出来る. curlの--data-urlencodeオプションを利用して置換後のqueryを更に%エンコードした. -oオプションを利用すると受信データをファイルへ出力できる. 後は受信したデータであるXMLファイルを標準出力へ出力すれば良い. Rubyでは'rexml/document'をrequireすればXMLを扱えるようになる.
xml = REXML::Document.new(open("#{path}/wolfram.xml"))
とすれば,受信したデータ"wolfram.xml"をRubyで扱えるようになる. eachメソッドを利用するとXML(ルート)の子要素を走査出来る.
xml.elements.each('queryresult/pod') do |pod|
  podはxml/queryresult/の子要素pod
end
コード中のxmlは,開いたXMLファイルのルートを表している. queryresult中のpodにはクエリに対する返答が収まっているので,eachメソッドを利用してpod中のsubpod/plaintextを出力すれば良い. 他にも付加情報としてspellcheck(スペルチェック),didyoumean(クエリ近似),reinterpret(再評価),assumption(仮定)要素を出力している. これら付加情報を見れば,自分の入力したクエリがWolfram|Alphaにどのように解釈されているかをユーザが確認出来る.
  ちなみに,ロード中のアニメーションはThread.newすることで実現している. これは並行処理を行っていることを意味する. curlコマンドを実行する主スレッドに加え,アニメーションを実行する副スレッドを新たに用意したのだ. yieldによりcurlコマンドの実行終了を検知し,Threadをjoinすることで副スレッドを解放している. "\b"をprintすれば表示している文字列を一文字削除できるし,"\r"をprintすればカーソルを先頭へ移動出来るので,その後に出力する文字列で今ある文字列を上書き出来る.

5301002901270638393 http://www.storange.jp/2014/04/behind-code-wolframalpha-for-terminal.html http://www.storange.jp/2014/04/behind-code-wolframalpha-for-terminal.html Behind the Code - Wolfram|Alpha for Terminal 2014-04-16T15:32:00+09:00 http://www.storange.jp/2014/04/behind-code-wolframalpha-for-terminal.html Hideyuki Tabata 200 200 72 72