web-dev-qa-db-fra.com

Alias ​​de classe In Ruby

Je développe un nouveau Rails application basé sur un autre existant similaire. Dans mon ancienne application, j'ai une classe de coupon, qui est très similaire au billet dans ma nouvelle application. Je veux réutiliser tout le code Au coupon, mais avec un nouveau nom de classe.

Étant donné que le refactoring est lourde dans les rails, je me demande s'il existe un moyen de créer un alias pour une classe in Ruby (semblable à l'alias pour les attributs et les méthodes).

43
AdamNYC

Les cours n'ont pas de noms dans Ruby. Ce ne sont que des objets assignés à des variables, tout comme n'importe quel autre objet. Si vous souhaitez vous référer à une classe via une variable différente, attribuez-la à une variable différente:

Foo = String
88
Jörg W Mittag

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 constante

16
Siwei Shen 申思维

Toute personne venant ici à la recherche d'alias A Rails Classe de modèle à 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 que je n'obtiens pas une erreur constante non initialisée. par exemple.

# models/foo.rb
Foo = Bar

Aussi, vous pouvez trouver une étrangeté essayant d'utiliser l'alias dans des associations comme has_many, has_onec, etc. J'ai trouvé que vous pouvez généralement me contourner de ceux en utilisant l'espace de noms root (ou l'espace de noms approprié en fonction de la structure de vos modèles) pour vous assurer Rails tente d'atténuer le droit constant:

has_many :foo, class_name: '::Foo'
5
Mark G.

Je suis d'accord avec Warhog, plus ou moins - mais je sous-classe le ticket de votre classe de coupon - de cette façon si vous devez effectuer des données de données, vous pouvez mettre le code dans votre classe de ticket.

2
chrispanda

Vous devez faire attention à cela, car si votre classe subit n'importe quel changement d'état (des fonctions ajoutées, des constantes modifiées, des variables de classe, etc.) L'état que votre classe était en quand L'alias était Instancié ne reflétera pas les modifications mises à jour de votre classe.

Afin de Évitez le tunnel carpien sans sacrifier la lisibilité , vous pouvez stocker une Lambda dans votre objet alias plutôt que la classe actuelle. Bien sûr, la Lambda contient la classe mais cela assure que votre alias appelle la version la plus tard Version de votre classe.

Je mets ceci dans mon supermanpatches.rb Rails Initializer (à l'intérieur de config/initializers/) ‡

LAP = lambda { LosAngelesParcel }

Maintenant, vous pouvez appeler cela en utilisant LAP[] Et une version fraîchement monnaie de votre classe sera chargée. (Vous permettant de créer des instances, par exemple, par l = LAP[].new)

s'exécute une fois lorsque Rails est chargé, puis est omnipré dans votre application, appelable n'importe où comme une variable globale mais "en lecture seule", afin de parler .

2
boulder_ruby