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

ma11hew28
la source
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
Jacob Relkin
la source
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

Darme
la source
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.

Bruno Rohée
la source
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
agenty
la source
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
Kamil Lelonek
la source
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
Doktor OSwaldo
la source
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.

Ajay
la source