Dois-je utiliser alias ou alias_method?


353

J'ai trouvé un billet de blog sur aliascontre alias_method. Comme le montre l'exemple donné dans ce billet de blog, je veux simplement alias une méthode à une autre dans la même classe. Que dois-je utiliser? Je vois toujours aliasutilisé, mais quelqu'un m'a dit que alias_methodc'est mieux.

Utilisation de l'alias

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias name full_name
end

User.new.name #=>Johnnie Walker

Utilisation de alias_method

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias_method :name, :full_name
end

User.new.name #=>Johnnie Walker

Lien du billet de blog ici


4
Ce message ne répond-il pas à votre question?
— moinudin

4
@marcog: Je l'ai lu et je ne suis pas convaincu. Définir des alias à l'intérieur des méthodes, ce n'est pas quelque chose que l'on devrait faire souvent.
— Boris Stitnicky

2
@digitalextremist link works
— lukas.pukenis

4
Le guide de style ruby ​​recommande désormais alias"lors de l'aliasing des méthodes dans la portée des classes lexicales" et alias_method"lors de l'aliasing des méthodes des modules, des classes ou des classes singleton à l'exécution" github.com/bbatsov/ruby-style-guide#alias-method-lexically
— jtzero

Réponses:


380

alias_methodpeut être redéfini si besoin est. (il est défini dans la Moduleclasse.)

aliasLe comportement de change en fonction de sa portée et peut parfois être assez imprévisible.

Verdict: Utilisez alias_method- cela vous donne une tonne de flexibilité.

Usage:

def foo
  "foo"
end

alias_method :baz, :foo

43
Qu'entendez-vous par imprévisible? Naïvement, on dirait que l'option moins flexible sera plus prévisible. Pouvez-vous également fournir un exemple pratique de la redéfinition de alias_method?
— Boris Stitnicky

7
exemple d'utilisation: alias :new_method_name :old_method_nameOUalias_method :new_method_name, :old_method_name
— boulder_ruby

10
Le mot qu'il cherche ici est plus de résultats attendus . alias_methodest déterminé au moment de l'exécution et non pas lorsque le code est lu, par exemple alias, il se comporte donc plus comme prévu .
— Joshua Pinter

4
s'attendre à ce que les méthodes soient définies à la volée pendant l'exécution n'est pas ce que la plupart des programmeurs attendent. Au moins, c'est comme voler des cochons pour moi.
— akostadinov

10
On pourrait argumenter la même chose pour defvs define_method.: " define_methodpeut être redéfini si besoin est. (Il est défini dans la Moduleclasse.) defLe comportement du changement change en fonction de sa portée et peut être assez imprévisible parfois. Verdict: Utilisez define_method- cela vous donne une tonne plus de flexibilité. "
— Daniel Rikowski

62

Outre la syntaxe, la principale différence réside dans la portée :

# scoping with alias_method
class User

  def full_name
    puts "Johnnie Walker"
  end

  def self.add_rename
    alias_method :name, :full_name
  end

end

class Developer < User
  def full_name
    puts "Geeky geek"
  end
  add_rename
end

Developer.new.name #=> 'Geeky geek'

Dans le cas ci-dessus, la méthode "nom" sélectionne la méthode "nom_complet" définie dans la classe "Développeur". Essayons maintenant avec alias.

class User

  def full_name
    puts "Johnnie Walker"
  end

  def self.add_rename
    alias name full_name
  end
end

class Developer < User
  def full_name
    puts "Geeky geek"
  end
  add_rename
end

Developer.new.name #=> 'Johnnie Walker'

Avec l'utilisation de l'alias, la méthode «nom» n'est pas en mesure de choisir la méthode «full_name» définie dans Developer.

C'est parce que aliasc'est un mot-clé et il a une portée lexicale. Cela signifie qu'il est considéré selfcomme la valeur de soi au moment où le code source a été lu. alias_methodTraite en revanche selfcomme la valeur déterminée au moment de l'exécution.

Source: http://blog.bigbinary.com/2012/01/08/08/alias-vs-alias-method.html


35

Un point en faveur de aliaslieu de alias_methodest que sa sémantique est reconnue par rdoc, conduisant à des références croisées soignées dans la documentation générée, tandis que rdoc ignore complètement alias_method.


56
RDoc devrait peut-être commencer à traiter alias_method de la même manière que alias. Nous devrions leur en parler;)
— Szymon Jeż

9
Comment RDoc est-il censé comprendre les conséquences d'une méthode évaluée au moment de l'exécution?

@ user1115652 Est-ce votre point que quelqu'un pourrait avoir patché avec un singe alias_method? Cela semble vraiment peu probable, et si quelqu'un le fait, il devrait être prêt à en subir les conséquences dans RDoc. Si vous dites que c'est impossible, alors pourquoi pensez-vous cela et comment pensez-vous que Yardoc le fait?
— iconoclaste du

35

Je pense qu'il y a une règle non écrite (quelque chose comme une convention) qui dit d'utiliser 'alias' juste pour enregistrer un alias de nom de méthode, signifie que si vous aimez donner à l'utilisateur de votre code une méthode avec plus d'un nom:

class Engine
  def start
    #code goes here
  end
  alias run start
end

Si vous devez étendre votre code, utilisez la méta alternative ruby.

class Engine
  def start
    puts "start me"
  end
end

Engine.new.start() # => start me

Engine.class_eval do
  unless method_defined?(:run)
    alias_method :run, :start
    define_method(:start) do
      puts "'before' extension"
      run()
      puts "'after' extension"
    end
  end
end

Engine.new.start
# => 'before' extension
# => start me
# => 'after' extension

Engine.new.run # => start me

23

Un an après avoir posé la question, vient un nouvel article sur le sujet:

http://erniemiller.org/2014/10/23/in-defense-of-alias/

Il semble que "tant d'hommes, tant d'esprits". De l'ancien article, l'auteur encourage à utiliser alias_method, tandis que ce dernier suggère d'utiliser alias.

Cependant, il existe un aperçu commun de ces méthodes dans les articles de blog et les réponses ci-dessus:

  • utiliser aliaslorsque vous souhaitez limiter l'aliasing à l'étendue où il est défini
  • utiliser alias_methodpour permettre aux classes héritées d'y accéder

16

Les contributeurs de rubocop gem proposent dans leur Ruby Style Guide :

Préférez l'alias lors de l'aliasing des méthodes dans la portée de la classe lexicale car la résolution de self dans ce contexte est également lexicale, et il communique clairement à l'utilisateur que l'indirection de votre alias ne sera pas modifiée au moment de l'exécution ou par une sous-classe, sauf explication explicite.

class Westerner
  def first_name
   @names.first
  end

 alias given_name first_name
end

Utilisez toujours alias_method lorsque vous aliasez des méthodes de modules, de classes ou de classes singleton au moment de l'exécution, car la portée lexicale de l'alias conduit à l'imprévisibilité dans ces cas

module Mononymous
  def self.included(other)
    other.class_eval { alias_method :full_name, :given_name }
  end
end

class Sting < Westerner
  include Mononymous
end

0

alias_method new_method , old_method

old_method sera déclaré dans une classe ou un module qui est maintenant hérité de notre classe où new_method sera utilisé.

ceux-ci peuvent être variables ou la méthode à la fois.

Supposons que Class_1 possède old_method et que Class_2 et Class_3 héritent tous les deux de Class_1.

Si l'initialisation de Class_2 et Class_3 est effectuée dans Class_1, les deux peuvent avoir un nom différent dans Class_2 et Class_3 et son utilisation.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.