Supprimer / annuler la définition d’une méthode de classe

Vous pouvez définir dynamicment une méthode de classe pour une classe comme celle-ci:

class Foo end bar = %q{def bar() "bar!" end} Foo.instance_eval(bar) 

Mais comment faire le contraire: supprimer / dé-définir une méthode de classe? Je soupçonne que les méthodes remove_method et undef_method du module peuvent être utilisées à cette fin, mais tous les exemples que j’ai vus depuis Google Googling pendant des heures ont été utilisés pour supprimer / supprimer des méthodes d’ instance et non des méthodes de classe. Ou peut-être y a-t-il 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 < undefined method `bar' for Foo:Class (NoMethodError) 

Lorsque vous définissez une méthode de classe comme Foo.bar, Ruby la met en classe. Ruby ne peut pas le mettre dans Foo, car ce serait alors une méthode d’instance. Ruby crée la classe propre de Foo (aka “singleton class”), définit la super-classe de la classe propre sur la super-classe de Foo, puis définit la super-classe de Foo sur la classe propre:

 Foo -------------> Foo(eigenclass) -------------> Object super def bar super 

C’est pourquoi nous devons ouvrir la class < propre de Foo en utilisant la class < pour supprimer la barre de méthode.

Cela fonctionne aussi pour moi (je ne sais pas s’il existe 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, alors que remove_method supprime de cette classe, mais il sera toujours défini sur les super-classes 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. La plus gentille

 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 en 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 calculasortingce, vous devez utiliser des classes propres telles que:

 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 voie est meilleure que les autres réponses, car ici j'ai utilisé class_eval avec block. A mesure que vous bloquez l’espace de noms actuel, vous pouvez utiliser vos variables pour supprimer des méthodes

Object.send (: remove_const,: Foo)