Ceci est utile si vous essayez de créer des méthodes de classe de manière métaprogrammée:
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
Ma réponse à suivre ...
Je pense que dans Ruby 1.9, vous pouvez le faire:
class A
define_singleton_method :loudly do |message|
puts message.upcase
end
end
A.loudly "my message"
# >> MY MESSAGE
Je préfère utiliser send pour appeler define_method, et j'aime aussi créer une méthode de métaclasse pour accéder à la métaclasse:
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
C'est la manière la plus simple de Ruby 1.8+:
class A
class << self
def method_name
...
end
end
end
Dérivé de: Jay et Why , qui fournissent également des moyens de rendre cela plus joli.
self.create_class_method(method_name)
(class << self; self; end).instance_eval do
define_method method_name do
...
end
end
end
Update: extrait de la contribution de VR ci-dessous; une méthode plus concise (tant que vous ne définissez qu'une méthode de cette façon) qui est toujours autonome:
self.create_class_method(method_name)
(class << self; self; end).send(:define_method, method_name) do
...
end
end
mais notez que l'utilisation de send () pour accéder à des méthodes privées comme define_method () n'est pas forcément une bonne idée (si j'ai bien compris, cela va disparaître dans Ruby 1.9).
À utiliser dans Rails si vous souhaitez définir des méthodes de classe de manière dynamique, par souci:
module Concerns::Testable
extend ActiveSupport::Concern
included do
singleton_class.instance_eval do
define_method(:test) do
puts 'test'
end
end
end
end
Vous pouvez aussi faire quelque chose comme ça sans faire appel à 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