J'ai trouvé un article de blog sur alias
vs. alias_method
. Comme le montre l'exemple donné dans cet article de blog, je veux simplement aliaser une méthode avec une autre dans la même classe. Que devrais-je utiliser? Je vois toujours que alias
est utilisé, mais quelqu'un m'a dit que alias_method
est meilleur.
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
alias_method
peut être redéfini si besoin est. (Il est défini dans la classe Module
.)
Le comportement de alias
change en fonction de sa portée et peut parfois être assez imprévisible.
Verdict: Utilisez alias_method
- cela vous donne beaucoup plus de flexibilité.
Usage:
def foo
"foo"
end
alias_method :baz, :foo
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 "name" choisit la méthode "full_name" définie dans la classe "Developer". 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 d'alias, la méthode "name" n'est pas en mesure de choisir la méthode "full_name" définie dans Developer.
En effet, alias
est un mot clé et sa portée est lexicale. Cela signifie qu'il considère self
comme la valeur de self au moment de la lecture du code source. En revanche, alias_method
traite self
comme la valeur déterminée au moment de l'exécution.
Source: http://blog.bigbinary.com/2012/01/08/alias-vs-alias-method.html
Je pense qu'il existe une règle non écrite (quelque chose qui ressemble à une convention) qui dit d'utiliser "alias" uniquement pour enregistrer un alias de nom de méthode. Cela signifie que si vous souhaitez 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 avez besoin d'é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
Un point en faveur de alias
au lieu de alias_method
est que sa sémantique est reconnue par rdoc, ce qui conduit à des références croisées claires dans la documentation générée, tandis que rdoc ignore complètement alias_method
.
Un an après avoir posé la question, voici 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". Dans le premier article, l'auteur encourage l'utilisation de alias_method
, tandis que le dernier suggère d'utiliser alias
.
Cependant, il existe un aperçu commun de ces méthodes dans les deux blogs et réponses ci-dessus:
alias
lorsque vous souhaitez limiter le crénelage à la portée où il est définialias_method
pour permettre aux classes héritées d'y accéderCeci est maintenant traité dans le Ruby Style Guide :
Préférez alias lorsque les méthodes d'alias dans l'étendue de classe lexicale, car la résolution de self dans ce contexte est également lexique et indique clairement à l'utilisateur que l'indirection de votre alias ne sera pas modifiée au moment de l'exécution ni par aucune sous-classe, à moins d'indication 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 à l'exécution, car la portée lexicale de l'alias entraîne une 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
alias_methodnew_method, old_method
old_method sera déclaré dans une classe ou un module hérité de notre classe où new_method sera utilisé.
ceux-ci peuvent être variables ou méthodes les deux.
Supposons que Class_1 a 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.