开发者

Add ruby class methods or instance methods dynamically

开发者 https://www.devze.com 2023-04-04 03:40 出处:网络
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 m

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"开发者_C百科 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消