如何通过使用单例类外部的变量动态创建类方法?

时间:2016-05-22 20:40:32

标签: ruby

在MyClass中,我有一个类方法,它动态创建某些实例方法(使用define_method)。但是,我还想动态创建类方法。

如下所示,我正在使用class << self并在此范围内调用define_method(实际上我不确定范围是否是正确使用的词,尽管块似乎也不是正确。引用class << self内部执行的所有内容的正确术语是什么?)来定义类方法。

但是,我想使用来自class << self之外的变量命名类方法,即column_name

因此,我想使用column_name中的变量class << self来命名define_method中的类方法。 我尝试运行create_methods时收到错误:

  

NameError:未定义的局部变量或方法'column_name'for#   来自(pry):7:'单身课'

class MyClass
  @columns = ['col1', 'col2']  
  def self.create_methods  
    @columns.each do |column_name|
      define_method(column_name) { |column_name| puts column_name }    
      class << self    
        define_method(column_name) { |column_name| puts "class_method defined" }      
      end  
    end  
  end
end

如何从单例类中访问变量?在这里完成我想要完成的任务的最佳方法是什么(创建类方法)?

注意:我已经尝试了define_singleton_method方法,它似乎适用于我想要做的事情。它完全符合我的目标吗?即使这样,我关于使用class << self的问题仍然存在。

1 个答案:

答案 0 :(得分:1)

要完成您想要的任务,您可以:

class MyClass
    @@columns = ['col1', 'col2']  

    def self.create_methods  
        @@columns.each do |column_name|
            define_method(column_name) { |column_name| puts column_name }    
        end

        class << self
            @@columns.each do |column_name|
                define_method(column_name) { |col_name| puts "class_method defined" }      
            end
        end
    end
end

注意:使用def self."method_name"定义类方法可以使用实例变量(即@columns),这就是我重新定义为类变量的原因。

当您打开单件类(class << self)时,会丢失先前的作用域,因此您无法获得column_name(名称错误)。但是可以访问类变量。

在您的情况下,请使用define_singleton_method。如下:

class MyClass
    @columns = ['col1', 'col2']  

    def self.create_methods  
        @columns.each do |column_name|
            define_method(column_name) { |column_name| puts column_name }    
            define_singleton_method(column_name) { |col_name| puts "class_method defined" }
        end
    end
end