【问题标题】:Ruby: why instance eval on class creating instance method instead of class methodRuby:为什么在类上创建实例方法而不是类方法的实例评估
【发布时间】:2016-08-28 12:55:12
【问题描述】:

我想动态创建类方法test,为此我在instance_eval 中使用define_method 方法。我期待下面的代码创建类方法test,但代码创建的是实例方法test。这可能是什么原因?下面是我的代码。

module Accessor
  def define_accessor_for_class(method)
    self.instance_eval do
      define_method :test do
      end
    end
  end
end




class Employee
  extend Accessor
  define_accessor_for_class :name
end


Employee.name = "sanjay"
Employee.name

Employee.instance_methods(false) ==> [:test]
Employee.methods(false) => []

【问题讨论】:

    标签: ruby-on-rails ruby metaprogramming


    【解决方案1】:

    instance_eval 更改 self,即实例变量和无接收消息发送的动态上下文。它不会改变default definee,即不合格方法定义的动态上下文。

    在您的情况下,由于您的方法定义没有什么是动态的,因此根本没有理由使用动态元编程,您可以只使用合格的方法定义:

    module Accessor
      def define_accessor_for_class(method)
        def self.test; end
      end
    end
    
    class Employee
      extend Accessor
      define_accessor_for_class :name
    end
    
    Employee.instance_methods(false) #=> []
    Employee.methods(false)          #=> [:test]
    

    如果出于某种原因,您需要活力,您可以改用Object#define_singleton_method:

    module Accessor
      def define_accessor_for_class(method)
        define_singleton_method(:test) do end
      end
    end
    
    class Employee
      extend Accessor
      define_accessor_for_class :name
    end
    
    Employee.instance_methods(false) #=> []
    Employee.methods(false)          #=> [:test]
    

    【讨论】:

      【解决方案2】:

      您需要使用define_singleton_method 而不是define_method。

      module Accessor
        def define_accessor_for_class(method)
          self.instance_eval do
            define_singleton_method :test do
            end
          end
        end
      end
      

      单例方法是存在于单例类中的方法,并且仅可用于单个对象(与可用于该类的所有实例的常规实例方法不同)。在你的类中,它就像一个类方法。

      这是结果

      Employee.instance_methods(false) #=> []
      Employee.methods(false)          #=> [:test]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-06-11
        • 2016-01-13
        • 2018-11-23
        • 1970-01-01
        • 2012-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多