RubyでJavaScriptのプロトタイプもどき
prototype - 素人がプログラミングを勉強するブログの続き。RubyユーザがJavaScriptのオブジェクト指向を学ぶ時に使えるかもしれない。
=begin JavaScriptのようなオブジェクトの実装。 JSObject.newがJavaScriptのnew Object()相当であり、プロパティへの代入で値をセットする。 =end class JSObject < Object # Ruby1.9ならBasicObjectを継承すべき def initialize @object = {} end =begin JavaScriptのobject["key"]構文の実装。 objectのハッシュテーブルからキーで探し、無かったら"__proto__"プロパティから探し…と再帰的に動く。 "__proto__"がnilだったらnilを返す。 実体はprivate関数のref =end def [](name) ref(@object, name) end =begin 値の代入は__proto__とは関係がない =end def []=(name, value) @object[name] = value end =begin JavaScriptの.演算子相当の実装。ほとんどの処理を[]と[]=へ移譲。 =end def method_missing(name, value=nil) if name.to_s =~ /=$/ self[name.to_s[0..-2]] = value else self[name.to_s] end end private def ref(obj, name) if obj.has_key?(name) obj[name] elsif obj["__proto__"].nil? nil else ref(obj["__proto__"], name) end end end =begin JavaScriptのようなコンストラクタの実装。 JSConstructorを継承しinitメソッドをオーバーライドして使う。 class F < JSConstructor def init;end def foo;end end F.new がJavaScriptでの function F(){} F.prototype.foo = function(){}; new F(); に相当する。 =end class JSConstructor attr_reader :this def initialize(*args) @this = JSObject.new @this.__proto__ = this.prototype init(*args) || @this end def init;end end =begin 実例。 JavaScriptでの、 function Position(x, y) { this.x = x; this.y = y; } Position.prototype.get_x = function () {return this.x;}; Position.prototype.get_y = function() {return this.y;}; Position.prototype.get_size = function () {return this.x * this.y;}; var pos = new Position(10, 20); document.writeln(pos.get_x()); document.writeln(pos.get_y()); document.writeln(pos.get_size()); に相当する。 =end class Position < JSConstructor def init(x, y) this.x = x this.y = y end def get_x this.x end def get_y this.y end def get_size this.x * this.y end end pos = Position.new(10, 20) puts pos.get_x # 10 puts pos.get_y # 20 puts pos.get_size # 30