Ruby / IRB : Supprimer dynamiquement une classe ou un module

Contrairement à Python, Ruby ne permet pas de supprimer / undefine une classe ou un module en lui attribuant nil :

[23] pry(main)> module Foo; end  
=> nil
[24] pry(main)> Foo.class
=> Module
[25] pry(main)> Foo = nil
(pry):69: warning: already initialized constant Foo
(pry):66: warning: previous definition of Foo was here
=> nil
[27] pry(main)> Foo.class
=> NilClass
[28] pry(main)> module Foo; end
TypeError: Foo is not a module

Ce comportement s’explique par le fait qu’une classe ou un module est avant tout une constante, d’où le already initialized constant Foo.

Heureusement, il existe une méthode privée remove_const pour supprimer du contexte une constante. Visibilité privée oblige, impossible de faire directement Foo.remove_const :

[30] pry(main)> Foo.remove_const
NoMethodError: private method `remove_const' called for Foo:Module

La solution est d’appeler remove_const par l’intermédiaire de Object (Object is the default root of all Ruby objects.) :

[6] pry(main)> Object.send(:remove_const, :Foo)
=> Foo
[7] pry(main)> Foo
NameError: uninitialized constant Foo

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s