我想编写一个方法,它接受一个参数并创建另一个方法,用这个参数命名。这是我的代码
class Class
def createMethod(attr_name)
attr_name = attr_name.to_s
class_eval %Q{
def #{attr_name}
puts "bar"
end
}
end
end
p Class.new.createMethod("foo").respond_to?(:foo)
不幸的是,respond_to?(:foo)
评估为false
。怎么了?
答案 0 :(得分:3)
这是因为class_eval
是一个类方法,你在实例的上下文中调用它。你可以这样做:
class Class
def createMethod(attr_name)
attr_name = attr_name.to_s
self.class.class_eval %Q{
def #{attr_name}
puts "bar"
end
}
self # Return yourself if you want to allow chaining methods
end
end
这是irb
执行此操作时的输出:
irb(main):001:0> class Class
irb(main):002:1> def createMethod(attr_name)
irb(main):003:2> attr_name = attr_name.to_s
irb(main):004:2> self.class.class_eval %Q{
irb(main):005:2" def #{attr_name}
irb(main):006:2" puts "bar"
irb(main):007:2" end
irb(main):008:2" }
irb(main):009:2> end
irb(main):010:1> end
=> nil
irb(main):011:0> clazz = Class.new
=> #<Class:0x007fd86495cd58>
irb(main):012:0> clazz.respond_to?(:foo)
=> false
irb(main):013:0> clazz.createMethod("foo")
=> nil
irb(main):014:0> clazz.respond_to?(:foo)
=> true