2016-10-24 7 views
0

私がOpenStruct持ちの場合:openstructのcatch-allゲッターメソッド?

require 'ostruct' 
open_struct = OpenStruct.new 

を私はいくつかのケースで

open_struct.define_singleton_method(:[]) do |*args| 
    puts args.map(&:class) 
    puts args 
end 

open_struct.a = 1 
open_struct[:a] 
# => Symbol 
# a 

を動作しますが、ドットメソッドの構文を使用している場合、この[]メソッドが呼び出されていない[]を上書きすることができます。

open_struct.a 
# => 1 

OpenStructから継承し、Javascriptオブジェクトのように動作するクラスを作成しようとしています(基本的にはすべての

答えて

1

まず)の値として保存されているPROC上callを実行する必要性を取り除くためにrying - OpenStructすでに非常に多くの#[]#callの同義語であることを考えるとJavaScriptの()のような関数:

JS:

は、
foo = {} 
foo.bar = function() { console.log("Hello, world!"); }; 
foo.bar(); 
// => Hello, world! 

ルビー:

foo = OpenStruct.new 
foo.bar = proc { puts "Hello, world!" } 
foo.bar[] 
# => Hello, world! 

あなたはより多くのルビーのように機能を意味している場合 ...あなたはnew_ostruct_memberを上書きすることができます。

require 'ostruct' 

class AutoCallableOpenStruct < OpenStruct 
    protected def new_ostruct_member(name) 
    name = name.to_sym 
    unless respond_to?(name) 
     define_singleton_method(name) { 
     val = @table[name] 
     if Proc === val && val.arity == 0 
      val.call 
     else 
      val 
     end 
     } 
     define_singleton_method("#{name}=") { |x| modifiable[name] = x } 
    end 
    name 
    end 
end 

a = AutoCallableOpenStruct.new 
a.name = "max" 
a.helloworld = proc { puts "Hello, world!" } 
a.hello = proc { |name| puts "Hello, #{name}!" } 

a.name    # non-Proc, retrieve 
# => max 
a.helloworld  # nullary proc, autocall 
# => Hello, world! 
a.hello[a.name]  # non-nullary Proc, retrieve (#[] invokes) 
# => Hello, max! 

ちょうどRubyでOpenStructは、あなたのプログラムが遅くなり、そしてあなたはそれを避けることができれば、使用すべきではないことに注意してください。

関連する問題