Ruby:处理任意方法名称

时间:2016-10-12 23:23:59

标签: ruby

我记得看过Dave Thomas关于使用元编程创建方法名称的红宝石截屏,不需要遵守标识符语法要求。通常,标识符不得包含空格。他展示了如何用空格创建方法。但我不记得它是如何完成的。

我有include个Mongoid :: Document的类的任意字段名称。这样可以正常工作,其中_field可以是像'Hello World'这样的字符串:

MyClass.class_eval <<-EOS
  field :'#{ _field }', type: #{_type}
EOS

我想覆盖setter。所以我尝试了这个:

MyClass.class_eval <<-EOS
  field :'#{ _field }', type: #{_type}
  def #{ _field }=(val)
    self['#{ _field }'] = [self.send('#{ _field }')[0], val]
  end
EOS

不幸的是,如果_field是一个像'Hello World'这样的字符串,我会收到一个错误:

SyntaxError: (eval):2: formal argument cannot be a constant
           def Hello World=(val)

我怎样才能解决这个问题?

1 个答案:

答案 0 :(得分:4)

define_method可以让你这样做:

define_method(:"hello world") { puts 'hello world' }
send :"hello world"

但是你必须用send来调用它,因为不允许使用普通调用语法中的方法名。

您也可以从类定义中执行此操作。

class MyClass
  def name
    @name
  end

  define_method :"set name" do |new_name|
    @name = new_name
  end
end

instance = MyClass.new
instance.send :"set name", 'Bob'
instance.name #=> Bob

最后,我觉得有必要说这可能是一个糟糕的主意。我不确定完全你在这之后的目标,但可能有更好的方法。 :can != :should