「アンダースタンディング コンピュテーション」演習環境を整える
アンダースタンディング コンピュテーション―単純な機械から不可能なプログラムまで
- 作者: Tom Stuart,笹田耕一(監訳),笹井崇司
- 出版社/メーカー: オライリージャパン
- 発売日: 2014/09/18
- メディア: 大型本
- この商品を含むブログ (5件) を見る
この本は、情報系の大学の、オートマトンと計算理論にあたる部分を自習できる教材である。具体的にはRubyのREPL環境で、コンピュータを作っていくことになる。ただ、Ruby標準のREPLであるirbはコーディングには貧弱なので、少し準備してみた。
pryの出力方法を変更する
pryでそのまま実行しても、本と同じ出力を得られない。本では構文木構築の結果をirbの実行結果として
<<1 * 2 + 3 * 4>>
のように表示させるのだが、pryだと各オブジェクトの詳細まで出力してしまって、
=> #<struct Add left= #<struct Multiply left=#<struct Number value=1>, right=#<struct Number value=2>>, right= #<struct Multiply left=#<struct Number value=3>, right=#<struct Number value=4>>>
となってしまう。
元のirbと同じように出力するには、~/.pryrcに以下を記述する。
Pry.config.print = proc { |output, value| output.puts "=> #{value.inspect}" }
途中で中断したり、再開したりしたい
この本では、最初は空のクラスを作って、徐々に
モンキーパッチングで機能を追加->確認、追加->確認というふうに繰り返す。だから、クラスの全体像がわかるコードは登場しない。また、一旦REPL環境を閉じてしまうと、また最初から書き直しになってしまう。
方法A. モンキーパッチングによる追記はvimで、確認はpryで行うようにする。
いくつかやりかたがあるが、この方法の場合、クラスの書き間違いを修正しやすい。
2. 先にファイルを作る
$ touch simple.rb
3. 読み込む
pry(main)> require './simple'
または、pry起動時のオプションで渡す:
$ pry -r './simple'
4. クラスの追記
pry(main)> edit simple.rb
これでvimが開く。本のように、モンキーパッチング的にclass Numberを何回も書いていってもいいだろうし、class Number 〜〜 endの中に追記していってもいい。
(元から別ウィンドウで編集しててもOKな気がする。)
この時、ファイルを上書きするたびに読み込み直されてしまうので、クラス二重定義エラーが出る。
class Number < Struct.new(:value) end class Add < Struct.new(:left, :right) end class Multiply < Struct.new(:left, :right) end
pry(main)> edit simple.rb TypeError: superclass mismatch for class Number
仕方ないので、最初のスーパークラスを持たせる部分だけはInclude guard的なことをしておく。23ページのコードだったらこんな感じ。
unless defined? Number class Number < Struct.new(:value) end end unless defined? Add class Add < Struct.new(:left, :right) end end unless defined? Multiply class Multiply < Struct.new(:left, :right) end end class Number def to_s value.to_s end def inspect "<<#{self}>>" end end class Add def to_s "#{left} + #{right}" end def inspect "<<#{self}>>" end end class Multiply def to_s "#{left} * #{right}" end def inspect "<<#{self}>>" end end
こうしておけば、editコマンドによる編集後の自動再読みでエラーは出なくなり、
pry(main) > edit simple.rb
さらに、クラス名を指定して編集できるようになっている。
pry(main) > edit Number #vim起動時に自動でclass Numberの行まで移動
5. エディタを閉じて、実行してみる
リロード操作は不要
pry(main)> Add.new( Multiply.new(Number.new(1), Number.new(2)), Multiply.new(Number.new(3), Number.new(4)) ) => ...(出力)...
4, 5の工程の繰り返しで作業していく。
方法B. 実行履歴を保存、リロードする
この方法の場合、書いたクラスの完全版がわかるコードは得られないので注意。REPLの臨場感は損なわないのでサクっと進みたい人はいいかも。
デフォルトでpryは~/.pry_historyに履歴を溜め込んでいる。
History · pry/pry Wiki · GitHub
historyを眺め、hist --replay [m..n]というコマンドで再生できる。別ファイルに保存したい場合はhist --save [m..n] FILENAME で保存できる。