Ruby 动态定义参数
Ruby dynamically define arguments
我基本上想要实现的是:
arguments = [:foo, :bar]
multiplicator = ->(_something_funky_with_arguments_) { foo * bar }
multiplicator.call(3, 4) # => 12
除了将整个 lambda 构建为字符串并 eval
ing 之外,还有其他方法吗?
eval("->(#{arguments.join(', ')}) { foo * bar }")
像这样:
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 正确设置上下文:
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
我假设你想要动态参数
multiplicator = ->(args) { args.inject(:*) }
multiplicator.call([4,5,6])
=> 120
我基本上想要实现的是:
arguments = [:foo, :bar]
multiplicator = ->(_something_funky_with_arguments_) { foo * bar }
multiplicator.call(3, 4) # => 12
除了将整个 lambda 构建为字符串并 eval
ing 之外,还有其他方法吗?
eval("->(#{arguments.join(', ')}) { foo * bar }")
像这样:
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 正确设置上下文:
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
我假设你想要动态参数
multiplicator = ->(args) { args.inject(:*) }
multiplicator.call([4,5,6])
=> 120