¿Debo usar alias o alias_method?

353

He encontrado un blog el aliasfrente alias_method. Como se muestra en el ejemplo dado en esa publicación de blog, simplemente quiero alias un método a otro dentro de la misma clase. ¿Cuál debería usar? Siempre lo veo aliasusado, pero alguien me dijo que alias_methodes mejor.

Uso de alias

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias name full_name
end

User.new.name #=>Johnnie Walker

Uso de alias_method

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias_method :name, :full_name
end

User.new.name #=>Johnnie Walker

Enlace de publicación de blog aquí

ma11hew28
fuente
44
¿Esa publicación no responde tu pregunta?
moinudin
44
@marcog: Lo he leído y no estoy convencido. Definir alias dentro de los métodos, eso no es algo que uno deba hacer a menudo.
Boris Stitnicky, el
2
@digitalextremist enlace funciona
lukas.pukenis
44
La guía de estilo ruby ​​ahora recomienda alias"aliasing métodos en el ámbito de clase léxica" y alias_method"aliasing métodos de módulos, clases o clases singleton en tiempo de ejecución" github.com/bbatsov/ruby-style-guide#alias-method-lexically
jtzero

Respuestas:

380

alias_methodse puede redefinir si es necesario. (se define en la Moduleclase).

aliasEl comportamiento de los cambios depende de su alcance y puede ser bastante impredecible a veces.

Veredicto: Uso alias_method: te da mucha más flexibilidad.

Uso:

def foo
  "foo"
end

alias_method :baz, :foo
Jacob Relkin
fuente
43
¿Qué quieres decir con impredecible? Ingenuamente, uno diría que la opción que es menos flexible será más predecible. Además, ¿puede proporcionar algún ejemplo práctico de beneficio de redefinir alias_method?
Boris Stitnicky, el
77
ejemplo de uso: alias :new_method_name :old_method_nameORalias_method :new_method_name, :old_method_name
boulder_ruby
10
La palabra que está buscando aquí son los resultados más esperados . alias_methodse determina en tiempo de ejecución y no cuando se lee el código, como alias, por lo que se comporta más como lo esperaríamos .
Joshua Pinter
44
esperar que los métodos se definan sobre la marcha durante el tiempo de ejecución no es lo que la mayoría de los programadores esperan. Al menos es como los cerdos voladores para mí.
akostadinov
10
Uno podría argumentar lo mismo para defvs define_method.: " define_methodse puede redefinir si es necesario. ( Está definido en la Moduleclase). defEl comportamiento cambia dependiendo de su alcance y puede ser bastante impredecible a veces. Veredicto: Uso define_method: le da una tonelada más flexibilidad ".
Daniel Rikowski
62

Además de la sintaxis, la principal diferencia está en el alcance :

# 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'

En el caso anterior, el método "nombre" elige el método "nombre_completo" definido en la clase "Desarrollador". Ahora intentemos con 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'

Con el uso del alias, el método "nombre" no puede elegir el método "nombre_completo" definido en Developer.

Esto se debe a que aliases una palabra clave y tiene un alcance léxico. Significa que se trata selfcomo el valor de self en el momento en que se leyó el código fuente. Por el contrario, se alias_methodtrata selfcomo el valor determinado en el tiempo de ejecución.

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

Darme
fuente
35

Un punto a favor de en aliaslugar de alias_methodes que su semántica es reconocida por rdoc, lo que lleva a referencias cruzadas claras en la documentación generada, mientras que rdoc ignora por completo alias_method.

Bruno Rohée
fuente
56
Quizás RDoc debería comenzar a tratar alias_method de la misma manera que alias. Deberíamos contarles al respecto;)
Szymon Jeż
99
¿Cómo se supone que RDoc entiende las consecuencias de un método que se evalúa en tiempo de ejecución?
@ user1115652 ¿Su punto de vista de que alguien podría tener parches de mono alias_method? Eso parece realmente poco probable, y si alguien hace eso, entonces deberían estar dispuestos a sufrir las consecuencias en RDoc. Si su punto es que es imposible, ¿por qué piensa eso y cómo cree que lo hace Yardoc?
iconoclasta
35

Creo que hay una regla no escrita (algo así como una convención) que dice que usar 'alias' solo para registrar un alias de nombre de método, significa que si desea darle al usuario de su código un método con más de un nombre:

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

Si necesita extender su código, use la alternativa alternativa 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
edad
fuente
23

Un año después de hacer la pregunta llega un nuevo artículo sobre el tema:

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

Parece que "tantos hombres, tantas mentes". Desde el primer artículo, el autor anima a usar alias_method, mientras que el último sugiere usar alias.

Sin embargo, hay una descripción general común de estos métodos en las publicaciones de blog y las respuestas anteriores:

  • utilícelo aliascuando desee limitar el alias al alcance donde está definido
  • use alias_methodpara permitir que las clases heredadas accedan a él
Kamil Lelonek
fuente
16

Los contribuyentes de gemas rubocop proponen en su Guía de estilo Ruby :

Prefiera el alias cuando alias los métodos en el ámbito de la clase léxica, ya que la resolución de sí mismo en este contexto también es léxica, y le comunica claramente al usuario que la indirección de su alias no se alterará en el tiempo de ejecución o por ninguna subclase a menos que se haga explícito.

class Westerner
  def first_name
   @names.first
  end

 alias given_name first_name
end

Utilice siempre alias_method cuando alias los métodos de módulos, clases o clases singleton en tiempo de ejecución, ya que el alcance léxico de alias conduce a la imprevisibilidad en estos casos

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
fuente
0

alias_method new_method , old_method

old_method se declarará en una clase o módulo que se heredará ahora a nuestra clase donde se usará new_method .

Estos pueden ser variables o método ambos.

Supongamos que Class_1 tiene old_method, y Class_2 y Class_3 ambos heredan Class_1.

Si la inicialización de Class_2 y Class_3 se realiza en Class_1, ambos pueden tener un nombre diferente en Class_2 y Class_3 y su uso.

Ajay
fuente