47 votes

Alias de classe en Ruby

Je suis en train de développer une nouvelle application Rails basée sur une application existante similaire. Dans mon ancienne application, j'ai la classe Coupon, qui est très similaire à Ticket dans ma nouvelle application. Je veux réutiliser tout le code de Coupon, mais avec un nouveau nom de classe.

Comme le refactoring est lourd dans Rails, je me demande s'il existe un moyen de créer des alias pour une classe en Ruby (similaire aux alias pour les attributs et les méthodes).

95voto

Jörg W Mittag Points 153275

Les classes n'ont pas de nom en Ruby. Ce sont juste des objets assignés à des variables, comme tout autre objet. Si vous voulez faire référence à une classe via une autre variable, assignez-la à une autre variable :

Foo = String

19voto

Siwei Shen Points 5814

Dans le fichier coupon.rb :

class Coupon 
  #...
end

# add this line of code to make alias for class names
# option1. if you haven't defined a "Ticket" class: 
Ticket = Coupon   

# option2. if Ticket has been defined, you have to redefine it: 
Object.send :remove_const, "Ticket"
const_set "Ticket", Coupon

"Toute référence qui commence par une lettre majuscule, y compris les noms des classes et des modules, est une constante" -- << metaprogramming ruby>>, page38, section Constant.

7voto

Mark37 Points 1263

Toute personne qui vient ici cherche à savoir comment aliaser une classe de modèle rails pour avoir un nouveau nom :

J'ai pu simplement faire Foo = Bar mais j'ai dû mettre Foo à l'intérieur de son propre fichier modèle afin d'éviter une erreur de constante non initialisée.

# models/foo.rb
Foo = Bar

Vous pouvez également trouver des bizarreries en essayant d'utiliser l'alias dans des associations telles que has_many , has_one etc. J'ai découvert que vous pouvez généralement contourner ces problèmes en utilisant l'espace de nom Root (ou l'espace de nom approprié en fonction de la structure de vos modèles) pour vous assurer que Rails essaie de charger automatiquement la bonne constante :

has_many :foo, class_name: '::Foo'

4voto

boulder_ruby Points 6257

Il faut faire attention avec cela, car si votre classe subit un changement d'état (ajout de fonctions, modification de constantes, de variables de classe, etc.) l'état dans lequel se trouvait votre classe quand l'alias a été instancié ne reflétera pas les changements mis à jour dans votre classe.

Afin de éviter le canal carpien sans sacrifier la lisibilité Si vous avez une classe, vous pouvez stocker une lambda dans votre objet alias plutôt que dans la classe elle-même. Bien sûr, la lambda contient la classe, mais cela garantit que votre alias appellera la classe dernier site version de votre classe.

J'ai mis ça dans mon supermanpatches.rb initialisateur de rails (à l'intérieur de config/initializers/ ) ‡

LAP = lambda { LosAngelesParcel }

Vous pouvez maintenant l'appeler en utilisant LAP[] et une version fraîche de votre classe sera chargée. (Ce qui vous permet de créer des instances, par exemple en l = LAP[].new )

s'exécute une seule fois au chargement de rails et est ensuite omniprésente dans votre application. Elle peut être appelée n'importe où, un peu comme une variable globale, mais en lecture seule, pour ainsi dire. .

2voto

chrispanda Points 2368

Je suis plus ou moins d'accord avec Warhog, mais je sous-classerais ticket à partir de votre classe de coupon - de cette façon, si vous avez besoin de manipuler des données, vous pouvez placer le code dans votre classe de ticket.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X