动态定义方法中的默认参数

时间:2016-04-03 21:57:43

标签: ruby

我正在尝试动态定义方法并将参数传递给它。这就是我到目前为止所做的:

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做到了,但我还没能从代码中做出正面或反面。

2 个答案:

答案 0 :(得分:3)

您的问题不是很清楚,但我怀疑您正在寻找的功能是通常与instance_eval和朋友一起实现的。 instance_eval在其被调用者的上下文中计算给定块,以便在块内可以使用被调用者的实例方法和实例变量。

这是一个非常基本的例子:

"foo".instance_eval do
  puts size
  puts upcase
end
# -> 3
# -> FOO

sizeupcase不是我们给予块的参数,它们是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')