我记得看过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)
我怎样才能解决这个问题?
答案 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
。