Soll ich alias oder alias_method verwenden?


353

Ich fand eine Blog - Post auf aliasvs. alias_method. Wie in dem Beispiel in diesem Blog-Beitrag gezeigt, möchte ich einfach eine Methode einer anderen innerhalb derselben Klasse zuordnen. Welches soll ich verwenden? Ich sehe immer aliasgebraucht, aber jemand sagte mir, es alias_methodsei besser.

Verwendung von Alias

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias name full_name
end

User.new.name #=>Johnnie Walker

Verwendung von alias_method

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias_method :name, :full_name
end

User.new.name #=>Johnnie Walker

Blogpost Link hier


4
Beantwortet dieser Beitrag Ihre Frage nicht?
Moinudin

4
@marcog: Ich habe es durchgelesen und bin nicht überzeugt. Das Definieren von Aliasen innerhalb von Methoden sollte man nicht oft tun.
Boris Stitnicky

2
@digitalextremist Link funktioniert
lukas.pukenis

4
Der Ruby-Styleguide empfiehlt jetzt alias"beim Aliasing von Methoden im lexikalischen Klassenbereich" und alias_method"beim Aliasing von Methoden von Modulen, Klassen oder Singleton-Klassen zur Laufzeit" github.com/bbatsov/ruby-style-guide#alias-method-lexically
jtzero

Antworten:


380

alias_methodkann bei Bedarf neu definiert werden. (Es ist in der ModuleKlasse definiert .)

aliasDas Verhalten ändert sich je nach Umfang und kann manchmal ziemlich unvorhersehbar sein.

Fazit: Verwenden alias_method- es gibt Ihnen eine Tonne mehr Flexibilität.

Verwendungszweck:

def foo
  "foo"
end

alias_method :baz, :foo

43
Was meinst du mit unvorhersehbar? Naiv würde man sagen, dass die Option, die weniger flexibel ist, vorhersehbarer ist. Können Sie auch ein praktisches Beispiel dafür nennen, wie Sie von der Neudefinition von alias_method profitieren können?
Boris Stitnicky

7
Beispiel Anwendungsfall: alias :new_method_name :old_method_nameORalias_method :new_method_name, :old_method_name
boulder_ruby

10
Das Wort, nach dem er hier sucht, sind eher erwartete Ergebnisse. alias_methodwird zur Laufzeit bestimmt und nicht, wenn der Code gelesen wird alias, also verhält er sich mehr so, wie wir es erwarten würden .
Joshua Pinter

4
Die meisten Programmierer erwarten nicht, dass Methoden zur Laufzeit im laufenden Betrieb definiert werden. Zumindest ist es für mich wie fliegende Schweine.
Akostadinov

10
Man könnte dasselbe für defvs. argumentieren define_method: " define_methodKann bei Bedarf neu definiert werden. (Es wird in der ModuleKlasse definiert .) defDas Verhalten ändert sich je nach Umfang und kann manchmal ziemlich unvorhersehbar sein. Urteil: Verwenden define_method- es gibt Ihnen eine Menge mehr Flexibilität. "
Daniel Rikowski

62

Abgesehen von der Syntax liegt der Hauptunterschied im Umfang :

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

Im obigen Fall wählt die Methode "name" die in der Klasse "Developer" definierte Methode "full_name" aus. Versuchen wir es jetzt mit 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'

Bei Verwendung eines Alias ​​kann die Methode "name" die in Developer definierte Methode "full_name" nicht auswählen.

Dies liegt daran, dass aliases sich um ein Schlüsselwort handelt, das einen lexikalischen Gültigkeitsbereich hat. Dies bedeutet, dass es selfals der Wert von self zum Zeitpunkt des Lesens des Quellcodes behandelt wird. Im Gegensatz dazu wird als der zur Laufzeit ermittelte Wert alias_methodbehandelt self.

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


35

Ein Punkt, aliasder dafür alias_methodspricht, ist, dass seine Semantik von rdoc erkannt wird, was zu sauberen Querverweisen in der generierten Dokumentation führt, während rdoc dies vollständig ignoriert alias_method.


56
Vielleicht sollte RDoc anfangen, alias_method genauso zu behandeln wie alias. Wir sollten ihnen davon erzählen;)
Szymon Jeż

9
Wie soll RDoc die Konsequenzen einer Methode verstehen, die zur Laufzeit evaluiert wird?

@ user1115652 Ist Ihr Punkt, dass jemand Affen-Patches haben könntealias_method ? Das scheint wirklich unwahrscheinlich, und wenn jemand das tut, sollte er bereit sein, die Konsequenzen von RDoc zu tragen. Wenn Sie der Meinung sind, dass es unmöglich ist, warum denken Sie das und wie macht Yardoc das?
Bilderstürmer

35

Ich denke, es gibt eine ungeschriebene Regel (so etwas wie eine Konvention), die besagt, dass 'Alias' nur zum Registrieren eines Methodennamen-Alias ​​verwendet wird. Wenn Sie dem Benutzer Ihres Codes eine Methode mit mehr als einem Namen geben möchten:

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

Wenn Sie Ihren Code erweitern müssen, verwenden Sie die Ruby-Meta-Alternative.

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

Ein Jahr nach der Frage erscheint ein neuer Artikel zu diesem Thema:

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

Es scheint, dass "so viele Männer, so viele Köpfe". Aus dem ersteren Artikel ermutigt der Autor zur Verwendung alias_method, während der letztere die Verwendung vorschlägtalias .

Es gibt jedoch einen allgemeinen Überblick über diese Methoden sowohl in Blogposts als auch in den obigen Antworten:

  • verwenden alias Sie diese Option, wenn Sie das Aliasing auf den Bereich beschränken möchten, in dem es definiert ist
  • Verwenden Sie alias_methoddiese Option, um geerbten Klassen den Zugriff darauf zu ermöglichen

16

Die Rubocop-Edelstein-Mitwirkenden schlagen in ihrem Ruby Style Guide vor :

Bevorzugen Sie Aliasing, wenn Aliasing-Methoden im lexikalischen Klassenbereich, da die Auflösung von self in diesem Kontext ebenfalls lexikalisch ist, und es wird dem Benutzer klar mitgeteilt, dass die Indirektion Ihres Alias ​​zur Laufzeit oder durch eine Unterklasse nicht geändert wird, sofern dies nicht explizit angegeben wird.

class Westerner
  def first_name
   @names.first
  end

 alias given_name first_name
end

Verwenden Sie immer alias_method, wenn Sie zur Laufzeit Aliasing-Methoden für Module, Klassen oder Singleton-Klassen verwenden, da der lexikalische Umfang des Alias ​​in diesen Fällen zu Unvorhersehbarkeit führt

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 wird in einer Klasse oder einem Modul deklariert, das jetzt an unsere Klasse vererbt wird, in der new_method verwendet wird.

Diese können variabel sein oder beide Methoden.

Angenommen, Class_1 hat old_method und Class_2 und Class_3 erben beide Class_1.

Wenn die Initialisierung von Class_2 und Class_3 in Class_1 erfolgt, können beide in Class_2 und Class_3 und deren Verwendung unterschiedliche Namen haben.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.