我正在尝试动态定义方法并将参数传递给它。这就是我到目前为止所做的:
System.out.println("The Grade book contains: ");
printArray(mogrades);
调用class Commands
end
@commands = Commands.new
def route(name, &block)
Commands.send(:define_method, name, &block)
end
route 'foo' do
puts 'oh hai'
puts data
end
时,这就是我期望执行的内容:
route
此操作失败,因为除非我执行以下操作,否则未定义data = {name: 'foo', optional: 'bar'}
@commands.send(data['name'].to_sym, data)
:
data
有没有办法传递默认参数?看起来像是sinatrarb做到了,但我还没能从代码中做出正面或反面。
答案 0 :(得分:3)
您的问题不是很清楚,但我怀疑您正在寻找的功能是通常与instance_eval
和朋友一起实现的。 instance_eval
在其被调用者的上下文中计算给定块,以便在块内可以使用被调用者的实例方法和实例变量。
这是一个非常基本的例子:
"foo".instance_eval do
puts size
puts upcase
end
# -> 3
# -> FOO
size
和upcase
不是我们给予块的参数,它们是String对象上下文中已有的方法。
考虑到这一点,你可能会从这样的事情开始:
class Route
attr_reader :data
def initialize(name)
@data = { name: name, optional: "bar" }
end
end
rt = Route.new("foo")
rt.instance_eval do
puts 'oh hai'
puts data
end
# -> oh hai
# -> {:name=>"foo", :optional=>"bar"}
这里我们已经定义了一个Route类,其实例可以作为一个上下文来评估给予route
方法的块:
def route(name, &block)
rt = Route.new(name)
Commands.send(:define_method, name) do
rt.instance_eval(&block)
end
end
route 'foo' do
puts 'oh hai'
puts data
end
route 'qux' do
puts "My name is %{name} and optional is %{optional}" % data
end
@commands = Commands.new
@commands.foo
# -> oh hai
# -> {:name=>"foo", :optional=>"bar"}
@commands.qux
# -> My name is qux and optional is bar
答案 1 :(得分:1)
该块是您传递给route
方法的块;你可以自由地传递任何你想要的东西,因此ruby不会抱怨任何数量的参数(直到实际调用@commands.foo
。)
可以为阻止参数指定默认值:
λ = lambda do |data = 'hello'|
puts data
end
并将此lambda传递给route
:
route 'foo', &λ
#⇒ "hello"
AFAIK,无法使用某种类型的黑客在外地binding
中显式分配局部变量:
block.binding.local_variable_set(:data, 'hello')