动态创建方法中的Ruby动态参数

我有以下几种方法定义:

method_name = :foo method_arguments = [:bar, :baz] method_mandatory_arguments = {:quux => true} method_body = ->{ quux ? bar + baz : bar - baz } 

所以我想得到一个真正的方法。 但是define_method没有任何动态定义方法参数的可能性。 我知道另一种使用class_eval的方法,但我知道用class_eval定义方法比使用define_method慢得多。 我怎么能有效地存档这个?

我在rails控制台中做了一些基准测试:

 class Foo; end n = 100_000 Benchmark.bm do |x| x.report('define_method') do n.times { |i| Foo.send(:define_method, "method1#{i}", Proc.new { |a, b, c| a + b + c }) } end x.report('class_eval') do n.times { |i| Foo.class_eval %Q{ def method2#{i}(a, b, c); a + b + c; end } } end end 

所以我得到了以下结果:

  user system total real define_method 0.750000 0.040000 0.790000 ( 0.782988) class_eval 9.510000 0.070000 9.580000 ( 9.580577) 

没有简单的方法可以使用class_eval或define_method来实现您的要求。 由于method_body是lambda,因此它只能访问在它之前定义的局部变量。

 method_body = ->{ quux ? bar + baz : bar - baz } quux = true method_body.call # undefined local variable or method 'quux' quux = true method_body = ->{ quux ? bar + baz : bar - baz } method_body.call # undefined local variable or method 'bar' 

我建议你修改你的要求。 如果您的方法体应该是lambda,请为其定义所有参数。 那么这自然适合define_method:

 method_body = ->(quux, bar = 0, baz = 0){ quux ? bar + baz : bar - baz } define_method(method_name, &method_body) 

如果您的方法体可以是字符串,则eval是唯一的选项:

 method_body = "quux ? bar + baz : bar - baz" eval <