How do I use define_method to create class methods?

前端 未结 6 1120
孤城傲影
孤城傲影 2020-11-30 20:34

This is useful if you are trying to create class methods metaprogramatically:

def self.create_methods(method_name)
    # To create instance methods:
    defi         


        
相关标签:
6条回答
  • 2020-11-30 20:57

    I prefer using send to call define_method, and I also like to create a metaclass method to access the metaclass:

    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
    
    0 讨论(0)
  • 2020-11-30 21:03

    This is the simplest way in Ruby 1.8+:

    class A
      class << self
        def method_name
          ...
        end
      end
    end
    
    0 讨论(0)
  • 2020-11-30 21:10

    Derived from: Jay and Why, who also provide ways to make this prettier.

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

    Update: from VR's contribution below; a more concise method (as long as you're only defining one method this way) that is still standalone:

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

    but note that using send() to access private methods like define_method() is not necessarily a good idea (my understanding is that it is going away in Ruby 1.9).

    0 讨论(0)
  • 2020-11-30 21:11

    To be used in Rails if you want to define class methods dynamically from concern:

    module Concerns::Testable
      extend ActiveSupport::Concern
    
      included do 
        singleton_class.instance_eval do
          define_method(:test) do
            puts 'test'
          end
        end
      end
    end
    
    0 讨论(0)
  • 2020-11-30 21:22

    You could also do something like this without relying on 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
    
    0 讨论(0)
  • 2020-11-30 21:23

    I think in Ruby 1.9 you can do this:

    class A
      define_singleton_method :loudly do |message|
        puts message.upcase
      end
    end
    
    A.loudly "my message"
    
    # >> MY MESSAGE
    
    0 讨论(0)
提交回复
热议问题