読者です 読者をやめる 読者になる 読者になる

素人がプログラミングを勉強していたブログ

プログラミング、セキュリティ、英語、Webなどのブログ since 2008

連絡先: すかいぷ:javascripter_  か javascripter あっと tsukkun.net skypeのほうがいいです

prototype

ruby

+で継承、|でマージ。JavaScriptのprototypeチェインをハッシュで実装したもの。

require 'forwardable'

class Prototype
  include Enumerable

  extend Forwardable

  def initialize(obj = {})
    @scope = obj.dup
    @scope["__proto__"] = nil
  end

  def []=(name, val)
    @scope[name] = val
  end

  def [](name)
    cur = @scope
    begin
      if cur.key?(name)
        cur = cur[name]
        break
      end
      cur = cur["__proto__"]
    end until cur.nil?
    cur
  end

  def_delegator :@scope, :key?, :key?

  def_delegator :@scope, :each, :each

  def +(obj)
    ret = Prototype.new(obj.dup)
    ret["__proto__"] = self
    ret
  end

  def |(obj)
    ret = Prototype.new
    ret["__proto__"] = self
    obj.each{|k, v|
      unless key?(k)
        ret[k] = v
      end
    }
    ret
  end
end

foo = Prototype.new({"hoge" => 1, "fuga" => 4})
puts foo["hoge"] # => 1
bar = Prototype.new({"hoge" => 2, "bzz" => 3})
puts foo["hoge"] # => 2
bar["__proto__"] = foo
puts foo["fuga"] # => 4
bar["fuga"] = 5
puts foo["fuga"] # => 4
puts (foo + bar)["hoge"] # => 2
puts (foo | bar)["hoge"] #=> 1