Vous pouvez définir dynamiquement une méthode de classe pour une classe comme ceci:
class Foo
end
bar = %q{def bar() "bar!" end}
Foo.instance_eval(bar)
Mais comment faites-vous le contraire: remove/undefine une méthode de classe? Je soupçonne le module remove_method
et undef_method
les méthodes peuvent être utilisées à cette fin, mais tous les exemples que j'ai vus après Googling pendant des heures ont été pour supprimer/dé-définir l'instance , pas les méthodes de classe. Ou peut-être qu'il existe une syntaxe que vous pouvez transmettre à instance_eval
pour le faire également.
Merci d'avance.
#!/usr/bin/Ruby1.8
class Foo
def Foo.bar
puts "bar"
end
end
Foo.bar # => bar
class <<Foo
remove_method :bar
end
Foo.bar # => undefined method `bar' for Foo:Class (NoMethodError)
Lorsque vous définissez une méthode de classe comme Foo.bar, Ruby met la classe propre de Foo. Ruby ne peut pas la mettre dans Foo, car alors ce serait un méthode d'instance. Ruby crée la classe propre de Foo (aka "classe singleton"), définit la superclasse de la classe propre sur la superclasse de Foo, puis définit la superclasse de Foo sur la classe propre:
Foo -------------> Foo(eigenclass) -------------> Object
super def bar super
C'est pourquoi nous devons ouvrir la classe propre de Foo en utilisant class <<Foo
pour supprimer la barre de méthodes.
Cela fonctionne également pour moi (je ne sais pas s'il y a des différences entre undef et remove_method):
class Foo
end
Foo.instance_eval do
def color
"green"
end
end
Foo.color # => "green"
Foo.instance_eval { undef :color }
Foo.color # => NoMethodError: undefined method `color' for Foo:Class
Je suppose que je ne peux pas commenter la réponse d'Adrian parce que je n'ai pas assez de crédibilité, mais sa réponse m'a aidé.
Ce que j'ai trouvé: undef
semble supprimer complètement la méthode de l'existence, tandis que remove_method
le supprime de cette classe, mais il sera toujours défini sur les superclasses ou autres modules qui ont été étendus sur cette classe, etc.
Vous pouvez supprimer une méthode de deux manières simples. Le drastique
Module#undef_method( )
supprime toutes les méthodes, y compris celles héritées. Le plus gentil
Module#remove_method( )
supprime la méthode du récepteur, mais laisse les méthodes héritées seules.
Voir ci-dessous 2 exemple simple -
Exemple 1 utilisant undef_method
class A
def x
puts "x from A class"
end
end
class B < A
def x
puts "x from B Class"
end
undef_method :x
end
obj = B.new
obj.x
result - main.rb: 15: in ': undefined method
x 'pour # (NoMethodError)
Exemple 2 utilisant remove_method
class A
def x
puts "x from A class"
end
end
class B < A
def x
puts "x from B Class"
end
remove_method :x
end
obj = B.new
obj.x
Résultat - $ Ruby main.rb
x d'une classe
Si vous souhaitez supprimer la méthode avec le nom qui calcule dinamiquement, vous devez utiliser des classes propres comme:
class Foo
def self.bar
puts "bar"
end
end
name_of_method_to_remove = :bar
eigenclass = class << Foo; self; end
eigenclass.class_eval do
remove_method name_of_method_to_remove
end
cette façon est meilleure que les autres réponses, car ici j'ai utilisé class_eval avec block. Comme vous bloquez maintenant voir l'espace de noms actuel, vous pouvez donc utiliser vos variables pour supprimer les méthodes de manière dinamique