113

如果您尝试以元编程方式创建类方法,这很有用:

def self.create_methods(method_name)
    # To create instance methods:
    define_method method_name do
      ...
    end

    # To create class methods that refer to the args on create_methods:
    ???
end

我要遵循的答案...

4

6 回答 6

203

我认为在 Ruby 1.9 中你可以这样做:

class A
  define_singleton_method :loudly do |message|
    puts message.upcase
  end
end

A.loudly "my message"

# >> MY MESSAGE
于 2010-11-08T17:26:00.010 回答
25

我更喜欢使用 send 来调用 define_method,我也喜欢创建一个元类方法来访问元类:

class Object
  def metaclass
    class << self
      self
    end
  end
end

class MyClass
  # Defines MyClass.my_method
  self.metaclass.send(:define_method, :my_method) do
    ...
  end
end
于 2009-04-15T17:21:10.757 回答
10

这是 Ruby 1.8+ 中最简单的方法:

class A
  class << self
    def method_name
      ...
    end
  end
end
于 2012-10-08T13:39:00.877 回答
8

如果您想从关注点动态定义类方法,请在 Rails 中使用:

module Concerns::Testable
  extend ActiveSupport::Concern

  included do 
    singleton_class.instance_eval do
      define_method(:test) do
        puts 'test'
      end
    end
  end
end
于 2015-11-19T06:47:42.083 回答
7

源自:JayWhy,他们也提供了使这个更漂亮的方法。

self.create_class_method(method_name)
  (class << self; self; end).instance_eval do
    define_method method_name do
      ...
    end
  end
end

更新:来自以下 VR 的贡献;一种更简洁的方法(只要您只以这种方式定义一种方法),它仍然是独立的:

self.create_class_method(method_name)
  (class << self; self; end).send(:define_method, method_name) do
    ...
  end
end

但请注意,使用 send() 访问像 define_method() 这样的私有方法不一定是个好主意(我的理解是它在 Ruby 1.9 中将消失)。

于 2009-04-15T17:06:55.317 回答
-1

你也可以在不依赖define_method的情况下做这样的事情:

A.class_eval do
  def self.class_method_name(param)
    puts param
  end
end

A.class_method_name("hello") # outputs "hello" and returns nil
于 2016-12-13T21:55:46.160 回答