[ruby] 어떻게 define_method를 사용하여 클래스 메소드를 생성합니까?

메타 프로그래밍 방식으로 클래스 메서드를 생성하려는 경우 유용합니다.

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

따라야 할 내 대답 …



답변

Ruby 1.9에서는 다음과 같이 할 수 있습니다.

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

A.loudly "my message"

# >> MY MESSAGE


답변

저는 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


답변

이것은 Ruby 1.8+에서 가장 간단한 방법입니다.

class A
  class << self
    def method_name
      ...
    end
  end
end


답변

출처 : Jay and Why , 누가 더 예쁘게 만드는 방법도 제공합니다.

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에서 사라질 것입니다).


답변

클래스 메서드를 동적으로 정의하려는 경우 Rails에서 사용됩니다.

module Concerns::Testable
  extend ActiveSupport::Concern

  included do
    singleton_class.instance_eval do
      define_method(:test) do
        puts 'test'
      end
    end
  end
end


답변

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


답변