Marcos
Marcos

Reputation: 25

ruby mixin with class methods, instance methods, and class variables

Do you know how to define @@method_names class variable so that both my_macro and invoke_methods can use it as intended? Thank you!

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

Upvotes: 1

Views: 3503

Answers (2)

Zabba
Zabba

Reputation: 65467

Here's a working version. Changes are commented:

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

Upvotes: 2

Victor Moroz
Victor Moroz

Reputation: 9225

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

Upvotes: 1

Related Questions