3

我想写一个方法,它接受一个参数并创建另一个方法,用这个参数命名。这是我的代码

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. 怎么了?

4

1 回答 1

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
于 2013-01-20T15:48:06.023 回答