2011-06-23 7 views
1

クラス変数を定義して、my_macroinvoke_methodsの両方を意図どおりに使用できるように知っていますか?ありがとうございました!クラスメソッド、インスタンスメソッド、およびクラス変数を含むruby mixin

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

たぶんINIT最初の '@@ method_names = []' '@@ method_names << method_name' – Zabba

+0

前に、私はこの試みた:' @@ method_names = [] @@ method_namesない限り、 @@ method_names << method_name'でも 'NameError:MyModule :: ClassMethods'の@@ method_namesの初期化されていないクラス変数 – 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

クラスメソッドからクラス変数にアクセスすることは可能です - それについて何を意味するのか分かりません( 'class A; @m =" hello "; def self.x; p @@ m; end; end; Ax; ))。しかし、私はあなたの声明の残りの部分に同意します。 – Zabba

関連する問題