3

1 つのパラメーターを取り、このパラメーターで名前を付けた別のメソッドを作成するメソッドを作成したいと考えています。これが私のコードです

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 に答える