c4se記:さっちゃんですよ☆

.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)

.。oO(此のblogは、主に音樂考察Programming に分類されますよ。ヾ(〃l _ l)ノ゙♬♪♡)

音樂は SoundCloud に公開中です。

考察は現在は主に Scrapbox で公表中です。

Programming は GitHub で開發中です。

Dart風のautomatic field initializationをRubyで

(草稿) Dart風の、constructor引数を自動的にinstance変数に代入するアレをRubyhttp://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. RubyClojure風loop-recur (末尾再帰) http://c4se.hatenablog.com/entry/2013/09/05/184937


今回はDartだよ。確か未だDartVMをChromiumでも実用出来ずに (Dartiumが必要)、dart2jsでJavaScriptへ変換しないと使へないDartだよ。
Dartにはconstructorに色々な構文が加えられてゐて、其の一つに"automatic field initialization"と云ふのが有るよ。其れをRubyで真似てみたよ。


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