(草稿) Dart風の、constructor引数を自動的にinstance変数に代入するアレをRubyで http://c4se.hatenablog.com/entry/2013/09/12/184432
の続きだ。前回に挙げたbugは潰した。
Lisence: Public Domain
GitHub: ne-sachirou/AutoAttrInit.rb https://github.com/ne-sachirou/AutoAttrInit.rb
前提
Rubyで他言語の阿れや此れやを羨ましがるシリーズだよ。前回はClojureのloop-recur構文を真似したよ。
cf. RubyでClojure風loop-recur (末尾再帰) http://c4se.hatenablog.com/entry/2013/09/05/184937
今回はDartだよ。確か未だDartVMをChromiumでも実用出来ずに (Dartiumが必要)、dart2jsでJavaScriptへ変換しないと使へないDartだよ。
Dartにはconstructorに色々な構文が加えられてゐて、其の一つに"automatic field initialization"と云ふのが有るよ。其れをRubyで真似てみたよ。
.。oO( #Dart のconstructorに引数で、ClassName(this.param1, this.param2) て書くと、instance変数に突っ込んでくれるsyntax sugarは素敵だったは https://t.co/xZnhcqjSR1 )
— さっちゃん☆あざとももんが?♪? (@ne_sachirou) August 14, 2013
.。oO( #Ruby にも欲しかったりした。def initialize @param1, @param2 end みたいな。) MRT: https://t.co/MCfU9ODvMj
— さっちゃん☆あざとももんが?♪? (@ne_sachirou) August 14, 2013
Rubyでは好く此んなcodeを書く。
class Point attr_accessor :x, :y def initialize x, y @x = x @y = y end end
何だ。@x = x; @y = y
って。愚かだ。
やった事
Dartのautomatic field initializationとは、此の様なものだ。
cf. Idiomatic Dart | Dart: Structured web apps https://www.dartlang.org/articles/idiomatic-dart/#automatic-field-initialization
class Point { num x, y; Point(this.x, this.y); } var p = new Point(2, 4); p.x == 2; p.y == 4;
此れをRubyに直訳すると、此うだ。
class Point attr_accessor :x, :y def initialize @x, @y; end end p = Point.new 2, 4 assert_equal 2, p.x assert_equal 4, p.y
然し此れはsyntax errorと成る。methodの引数に、instance変数を指定出来ない。其処で妥協して、Class classのinstance methodを呼んでやる風にする。
class Point attr_accessor :x, :y def initialize x, y; end auto_attr_init end p = Point.new 2, 4 assert_equal 2, p.x assert_equal 4, p.y
やったのは、此のauto_attr_init
methodを実装した事だ。AutoAttrInit::AutoAi
moduleにて定義し、Class classにincludeしてゐる。大体洞んな風に使へるのかは、実装下部のtest codeを読めば解ると思ふ。
内部実装を簡単に述べる。
auto_attr_init
は、initialize methodを定義した後に呼ぶ必要が有る。此れは呼ばれると、其のclassのinitialize methodを取得し、洞んなparameterが定義され、default値は何かを解析する。default値を解析する為に、initialize methodのsource codeを取得し (定義されてゐるfileをopenして取得する)、RipperでS式にしてdefault値部分を抜き出し、SorcererにてRubyのcodeに戻してゐる。
cf. RubyのS式を調べた。S式をRuby文字列に戻す方法も調べた http://c4se.hatenablog.com/entry/2013/09/13/132746
此んな大仰な事をしてゐるのは、全てdefault値を解析する為だ。Method#parameters
で一緒に取れれば好いのに。
此れで準備は完了した。実際に此のclassがnewでinstance化されると、initialize methodの本体が実行される直前に、引数と同名のinstance変数へ代入する処理を実行する。此所にはAspectRを使ってお手軽に楽をしてゐる。
実装
bug含みなのはわかるけど、気に成ったら直して。
AutoAttrInit.rb/lib at master · ne-sachirou/AutoAttrInit.rb https://github.com/ne-sachirou/AutoAttrInit.rb/tree/master/lib
test
AutoAttrInit.rb/test at master · ne-sachirou/AutoAttrInit.rb https://github.com/ne-sachirou/AutoAttrInit.rb/tree/master/test