2011-06-23 63 views
1

你知道如何定义@@method_names类变量,这样既my_macroinvoke_methods可以使用它作为故意的吗?谢谢!红宝石混入与类方法,实例方法和类变量

module MyModule 

    module ClassMethods  
     def my_macro method_name, options = { } 
      define_method method_name do 
       puts "defining #{method_name} with #{options}" 
      end 
      @@method_names << method_name 
     end  
    end 

    def invoke_methods 
     @@method_names.each { |method_name| send method_name } 
    end 

    def self.included includer 
     includer.extend ClassMethods 
    end 

end 

class MyClass 
    include MyModule 
    my_macro :method_foo, :bar => 5 
    my_macro :method_baz, :wee => [3,4] 
end 

MyClass.new.invoke_methods 
+1

也许初始化第一个'@@ method_names = []''之前@@ method_names << method_name' – Zabba

+0

我尝试这样做:'@@ method_names = []除非@@ method_names; @@ method_names << method_name'但得到'NameError:在MyModule中未初始化的类变量@@ method_names :: ClassMethods' – Marcos

+0

做的,而不是使用除非:'@@ method_names = @@ method_names || []' – Zabba

回答

2

这里有一个工作版本。变化被注释:

module MyModule 
    module ClassMethods 
     @@method_names ||= [] #move this up here 
     def my_macro method_name, options = { } 
      define_method method_name do 
       puts "defining #{method_name} with #{options}" 
      end 
      @@method_names << method_name 
     end 

     #added this (rename as required) 
     def the_methods 
      @@method_names 
     end 
    end 

    def invoke_methods 
     #changed this call 
     self.class.the_methods.each { |method_name| send method_name } 
    end 

    def self.included includer 
     includer.extend ClassMethods 
    end 
end 

class MyClass 
    include MyModule 
    my_macro :method_foo, :bar => 5 
    my_macro :method_baz, :wee => [3,4] 
end 

MyClass.new.invoke_methods 
+0

谢谢Zabba。这也适用! – Marcos

1
module MyModule 

    module ClassMethods  
     def my_macro method_name, options = { } 
      define_method method_name do 
       puts "defining #{method_name} with #{options}" 
      end 
      @method_names ||= [] 
      @method_names << method_name 
     end 

     def method_names 
      @method_names 
     end 
    end 

    def invoke_methods 
     self.class.method_names.each { |method_name| send method_name } 
    end 

    def self.included includer 
     includer.extend ClassMethods 
    end 

end 

class MyClass 
    include MyModule 
    my_macro :method_foo, :bar => 5 
    my_macro :method_baz, :wee => [3,4] 
end 

MyClass.new.invoke_methods 
+0

如何让它使用类变量而不是实例变量? – Zabba

+1

我不认为有可能从类方法访问类变量。类方法中的@@ var是非常奇怪的事情,不要这样做。通常不建议使用类变量,即使在“正常”情况下也是如此。 –

+0

它可以从一个类的方法访问类变量 - 不知道你的意思有关('A类的东西; @@ M =“你好”;高清self.x,P @@米;结束;结束;斧; ')。但我同意你的发言的其余部分。 – Zabba