简体   繁体   中英

Add ruby class methods or instance methods dynamically

I am quite new to Ruby, so still learning. I was researching quite a bit about how to add methods dynamically, and I was successful to create instance methods, but not successful when creating class methods.

This is how I generated instance methods:

  class B
    def before_method
      puts "before method"
    end

    def self.run(method)
        send :define_method, method do
          before_method
          puts "method #{method}"
        end
    end
  end

  class A < B
    run :m
    run :n
  end

Any idea about the best ways to create static methods?

My final task is to look for the best way to create "before" and "after" tasks for class methods.

To create instance methods dynamically, try

class Foo
  LIST = %w(a b c)

  LIST.each do |x|
    define_method(x) do |arg|
      return arg+5
    end
  end
end

Now any instance of Foo would have the method "a", "b", "c". Try

Foo.new.a(10)

To define class methods dynamically, try

class Foo
  LIST = %w(a b c)

  class << self
    LIST.each do |x|
      define_method(x) do |arg|
        return arg+5
      end
    end
  end
end

Then try

Foo.a(10)

Instance methods of an objects singleton class are singleton methods of the object itself. So if you do

class B
  def self.run(method)
    singleton_class = class << self; self; end
    singleton_class.send(:define_method, method) do
        puts "Method #{method}"
    end
  end
end

you can now call

B.run :foo
B.foo 
=> Method foo

(Edit: added B.run :foo as per Lars Haugseth's comment)

Here's something re-worked to use class methods:

class B
   def self.before_method
     puts "before method"
   end

  def self.run(method)
    define_singleton_method(method) do
      before_method
      puts "method #{method}"
    end
  end
end

Update: Using define_singleton_method from Ruby 1.9 which properly assigns to the eigenclass .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM