Dovrei usare alias o alias_method?


353

Ho trovato un post sul blog su aliasvs alias_method. Come mostrato nell'esempio fornito in quel post sul blog, voglio semplicemente creare un metodo con un altro all'interno della stessa classe. Quale dovrei usare? Lo vedo sempre aliasusato, ma qualcuno mi ha detto che alias_methodè meglio.

Uso dell'alias

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias name full_name
end

User.new.name #=>Johnnie Walker

Utilizzo di alias_method

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias_method :name, :full_name
end

User.new.name #=>Johnnie Walker

Link al post del blog qui


4
Quel post non risponde alla tua domanda?
Moinudin,

4
@marcog: l'ho letto e non ne sono convinto. Definire gli alias all'interno dei metodi, non è qualcosa che si dovrebbe fare spesso.
Boris Stitnicky,

2
Il collegamento @digitalextremist funziona
lukas.pukenis il

4
La guida allo stile ruby ​​ora raccomanda alias"quando aliasing metodi nell'ambito della classe lessicale" e alias_method"quando aliasing metodi di moduli, classi o classi singleton in fase di esecuzione" github.com/bbatsov/ruby-style-guide#alias-method-lexically
jtzero

Risposte:


380

alias_methodpuò essere ridefinito se necessario. (è definito nella Moduleclasse.)

aliasIl comportamento cambia a seconda del suo ambito e talvolta può essere abbastanza imprevedibile.

Verdetto: Usa alias_method- ti dà molta più flessibilità.

Uso:

def foo
  "foo"
end

alias_method :baz, :foo

43
Cosa intendi per imprevedibile. Incredibilmente, si direbbe che l'opzione meno flessibile sarà più prevedibile. Inoltre, puoi fornire qualche esempio pratico di beneficiare della ridefinizione di alias_method?
Boris Stitnicky,

7
esempio caso d'uso: alias :new_method_name :old_method_nameOPPUREalias_method :new_method_name, :old_method_name
boulder_ruby l'

10
La parola che sta cercando qui è risultati più attesi . alias_methodè determinato in fase di esecuzione e non quando il codice viene letto, ad esempio alias, quindi si comporta di più come ci aspetteremmo .
Joshua Pinter,

4
aspettarsi che i metodi siano definiti al volo durante il runtime non è quello che la maggior parte dei programmatori si aspetta. Almeno è come volare maiali per me.
Akostadinov,

10
Si potrebbe sostenere lo stesso per defvs define_method.: " define_methodpuò essere ridefinito se necessario. (È definito nella Moduleclasse.) defIl comportamento cambia a seconda del suo ambito e può essere alquanto imprevedibile. Verdetto: Usa define_method- ti dà un sacco maggiore flessibilità ".
Daniel Rikowski,

62

A parte la sintassi, la differenza principale sta nello scoping :

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

Nel caso precedente, il metodo "nome" seleziona il metodo "nome completo" definito nella classe "Sviluppatore". Ora proviamo 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 l'uso dell'alias il metodo "name" non è in grado di scegliere il metodo "full_name" definito in Developer.

Questo perché aliasè una parola chiave ed ha un ambito lessicale. Significa che considera selfil valore di sé al momento della lettura del codice sorgente. Al contrario, alias_methodconsidera selfil valore determinato in fase di esecuzione.

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


35

Un punto a favore aliasinvece di alias_methodè che il suo semantico è riconosciuto da rdoc, portando a riferimenti incrociati nella documentazione generata, mentre rdoc ignora completamente alias_method.


56
Forse RDoc dovrebbe iniziare a trattare alias_method allo stesso modo di alias. Dobbiamo dirglielo;)
Szymon Jeż

9
In che modo RDoc dovrebbe comprendere le conseguenze di un metodo valutato in fase di esecuzione?

@ user1115652 Secondo te qualcuno potrebbe aver patchato la scimmia alias_method? Sembra davvero improbabile, e se qualcuno lo fa, dovrebbe essere disposto a subire le conseguenze in RDoc. Se il tuo punto è che è impossibile, allora perché lo pensi e come pensi che lo faccia Yardoc?
Iconoclast,

35

Penso che ci sia una regola non scritta (qualcosa come una convenzione) che dice di usare 'alias' solo per registrare un alias nome-metodo, significa se ti piace dare all'utente del tuo codice un metodo con più di un nome:

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

Se è necessario estendere il codice, utilizzare la meta 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

23

Un anno dopo aver posto la domanda arriva un nuovo articolo sull'argomento:

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

Sembra che "così tanti uomini, così tante menti". Dall'articolo precedente l'autore incoraggia a usare alias_method, mentre il secondo suggerisce di usare alias.

Tuttavia c'è una panoramica comune di questi metodi in entrambi i post di blog e le risposte sopra:

  • utilizzare aliasquando si desidera limitare l'aliasing all'ambito in cui è definito
  • utilizzare alias_methodper consentire alle classi ereditate di accedervi

16

I donatori di gemme di rubocop propongono nella loro Guida allo stile Ruby :

Preferisci l'alias quando i metodi di aliasing nell'ambito della classe lessicale in quanto la risoluzione di sé in questo contesto è anche lessicale e comunica chiaramente all'utente che l'indirizzamento del tuo alias non verrà alterato in fase di esecuzione o da alcuna sottoclasse se non esplicitato.

class Westerner
  def first_name
   @names.first
  end

 alias given_name first_name
end

Usa sempre alias_method quando aliasing metodi di moduli, classi o classi singleton in fase di esecuzione, poiché l'ambito lessicale dell'alias porta a imprevedibilità in questi casi

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 verrà dichiarato in una classe o modulo che viene ereditato ora nella nostra classe in cui verrà utilizzato new_method .

questi possono essere variabili o metodo entrambi.

Supponiamo che Class_1 abbia old_method e Class_2 e Class_3 ereditino entrambe Class_1.

Se l'inizializzazione di Class_2 e Class_3 viene eseguita in Class_1, entrambi possono avere un nome diverso in Class_2 e Class_3 e il suo utilizzo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.