我基本上想要实现的是:
arguments = [:foo, :bar]
multiplicator = ->(_something_funky_with_arguments_) { foo * bar }
multiplicator.call(3, 4) # => 12
除了将整个lambda构建为字符串并eval
之外,还有其他办法吗?
eval("->(#{arguments.join(', ')}) { foo * bar }")
答案 0 :(得分:2)
像这样:
multiplicator = Proc.new {|*arguments| arguments.inject(&:*) }
multiplicator.call(3, 4) # => 12
multiplicator.call(3, 4, 5) # => 60
或者如果您更喜欢lambda语法:
multiplicator = ->(*arguments) { arguments.inject(&:*) }
multiplicator.call(3, 4) # => 12
multiplicator.call(3, 4, 5) # => 60
评论之后,也许这是你的解决方案:
foo = 3
bar = 4
arguments = ["foo", "bar"]
multiplicator = ->(bind) { arguments.inject(1) { |acc, var| acc * eval(var, bind)} }
multiplicator.call(binding) # => 12
经过更多评论后,再尝试两次: 更简单的:
require 'ostruct'
structer = OpenStruct.new
structer.foo = 3
structer.bar = 4
multiplicator = ->() { foo * bar }
structer.define_singleton_method :call_me, &multiplicator
structer.call_me # => 12
更复杂的一个使用代理类来正确设置上下文:
class Proxy
def set_lambda(lambda_object)
define_singleton_method :run_me, &lambda_object
return self
end
def call(arg_names, *args)
arg_names.each_with_index do |var, i|
define_singleton_method var do args[i] end
end
self.run_me
end
end
multiplicator = ->() { foo * bar }
arguments = [:foo, :bar]
Proxy.new.set_lambda(multiplicator).call(arguments, 3, 4)
经过大量评论后,我相信这是最接近OP请求的评论:
class Proxy
def set_lambda(lambda_object)
define_singleton_method :run_me, &lambda_object
return self
end
def set_arguments(args)
@args_table = args
return self
end
def call(*args)
@args_table.each_with_index do |var, i|
define_singleton_method var do args[i] end
end
self.run_me
end
end
multiplicator = ->() { foo * bar }
arguments = [:foo, :bar]
callable = Proxy.new.set_lambda(multiplicator).set_arguments(arguments)
callable.call(3, 4) # => 12
callable.call(4, 5) # => 20
答案 1 :(得分:0)
我假设你想拥有动态参数
multiplicator = ->(args) { args.inject(:*) }
multiplicator.call([4,5,6])
=> 120