Haruskah saya menggunakan alias atau alias_method?

353

Saya menemukan sebuah posting blog di aliasvs alias_method. Seperti ditunjukkan dalam contoh yang diberikan dalam posting blog itu, saya hanya ingin alias metode lain di dalam kelas yang sama. Yang mana yang harus saya gunakan? Saya selalu melihat aliasdigunakan, tetapi seseorang mengatakan kepada saya alias_methodlebih baik.

Penggunaan alias

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias name full_name
end

User.new.name #=>Johnnie Walker

Penggunaan alias_method

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias_method :name, :full_name
end

User.new.name #=>Johnnie Walker

Tautan posting blog di sini

ma11hew28
sumber
4
Bukankah posting itu menjawab pertanyaan Anda?
moinudin
4
@marcog: Saya sudah membacanya, dan saya tidak yakin. Mendefinisikan alias di dalam metode, itu bukanlah sesuatu yang harus sering dilakukan seseorang.
Boris Stitnicky
2
@digitalextremist tautan berfungsi
lukas.pukenis
4
Panduan gaya ruby ​​sekarang merekomendasikan alias"ketika aliasing metode dalam lingkup kelas leksikal" dan alias_method"ketika aliasing metode modul, kelas, atau kelas singleton saat runtime" github.com/bbatsov/ruby-style-guide#alias-method-lexically
jtzero

Jawaban:

380

alias_methoddapat didefinisikan ulang jika perlu. (Itu didefinisikan di Modulekelas.)

aliasPerubahan perilaku tergantung pada ruang lingkupnya dan terkadang tidak dapat diprediksi.

Putusan: Gunakan alias_method- itu memberi Anda lebih banyak fleksibilitas.

Pemakaian:

def foo
  "foo"
end

alias_method :baz, :foo
Jacob Relkin
sumber
43
Apa yang Anda maksud dengan tak terduga. Naif, orang akan mengatakan bahwa opsi yang kurang fleksibel akan lebih mudah diprediksi. Juga, dapatkah Anda memberikan contoh praktis manfaat dari mendefinisikan ulang alias_method?
Boris Stitnicky
7
contoh use case: alias :new_method_name :old_method_nameORalias_method :new_method_name, :old_method_name
boulder_ruby
10
Kata yang dia cari di sini adalah hasil yang lebih diharapkan . alias_methodditentukan pada saat runtime dan bukan ketika kode dibaca, seperti alias, sehingga lebih berperilaku seperti yang kita harapkan .
Joshua Pinter
4
mengharapkan bahwa metode didefinisikan dengan cepat selama runtime bukan seperti yang diharapkan kebanyakan programmer. Setidaknya itu seperti babi terbang bagiku.
akostadinov
10
Orang bisa berpendapat hal yang sama untuk defvs define_method.: " define_methoddapat didefinisikan ulang jika perlu. (Itu didefinisikan di Modulekelas.) def'S perubahan perilaku tergantung pada ruang lingkup dan kadang-kadang bisa sangat tidak terduga. Putusan: Gunakan define_method- itu memberi Anda satu ton lebih banyak fleksibilitas. "
Daniel Rikowski
62

Terlepas dari sintaks, perbedaan utama adalah dalam pelingkupan :

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

Dalam metode kasus di atas "nama" memilih metode "nama lengkap" yang didefinisikan dalam kelas "Pengembang". Sekarang mari kita coba 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'

Dengan penggunaan alias metode "nama" tidak dapat memilih metode "nama lengkap" yang ditentukan dalam Pengembang.

Ini karena aliaskata kunci dan cakupannya secara leksikal. Itu berarti memperlakukan selfsebagai nilai diri pada saat kode sumber dibaca. Sebaliknya alias_methodmemperlakukan selfsebagai nilai yang ditentukan pada waktu berjalan.

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

Darme
sumber
35

Satu hal yang lebih mendukung aliasdaripada itu alias_methodadalah bahwa semantiknya diakui oleh rdoc, yang mengarah ke referensi silang yang rapi dalam dokumentasi yang dihasilkan, sementara rdoc sepenuhnya diabaikan alias_method.

Bruno Rohée
sumber
56
Mungkin RDoc harus mulai memperlakukan alias_method sama dengan alias. Kita harus memberi tahu mereka tentang itu;)
Szymon Jeż
9
Bagaimana RDoc seharusnya memahami konsekuensi dari metode yang dievaluasi saat runtime?
@ user1115652 Apakah maksud Anda bahwa seseorang mungkin telah menambal monyet alias_method? Tampaknya sangat tidak mungkin, dan jika seseorang melakukan itu, maka mereka harus rela menanggung akibatnya di RDoc. Jika poin Anda adalah bahwa itu tidak mungkin, lalu mengapa Anda berpikir begitu dan bagaimana menurut Anda Yardoc melakukannya?
iconoclast
35

Saya pikir ada aturan tidak tertulis (sesuatu seperti konvensi) yang mengatakan untuk menggunakan 'alias' hanya untuk mendaftarkan nama metode alias, berarti jika Anda ingin memberikan pengguna kode Anda satu metode dengan lebih dari satu nama:

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

Jika Anda perlu memperpanjang kode Anda, gunakan alternatif meta 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
sumber
23

Setahun setelah mengajukan pertanyaan, muncul artikel baru tentang masalah ini:

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

Tampaknya "begitu banyak pria, begitu banyak pikiran." Dari artikel sebelumnya penulis mendorong untuk menggunakan alias_method, sedangkan yang terakhir menyarankan untuk menggunakan alias.

Namun ada gambaran umum dari metode ini di kedua blogpost dan jawaban di atas:

  • gunakan aliasketika Anda ingin membatasi alias ke ruang lingkup di mana ia didefinisikan
  • gunakan alias_methoduntuk memungkinkan kelas yang diwarisi untuk mengaksesnya
Kamil Lelonek
sumber
16

Para kontributor rubocop gem mengusulkan dalam Panduan Gaya Ruby mereka :

Lebih suka alias ketika aliasing metode dalam lingkup kelas leksikal sebagai resolusi diri dalam konteks ini juga leksikal, dan itu berkomunikasi dengan jelas kepada pengguna bahwa tipuan alias Anda tidak akan diubah saat runtime atau oleh subkelas apa pun kecuali dibuat secara eksplisit.

class Westerner
  def first_name
   @names.first
  end

 alias given_name first_name
end

Selalu gunakan alias_method ketika menggunakan metode modul, kelas, atau kelas tunggal pada saat runtime, karena ruang lingkup leksikal alias mengarah pada ketidakpastian dalam kasus-kasus ini

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

alias_method new_method , old_method

old_method akan dideklarasikan di kelas atau modul yang sedang diwarisi sekarang ke kelas kami di mana new_method akan digunakan.

ini bisa berupa variabel atau metode keduanya.

Misalkan Class_1 memiliki old_method, dan Class_2 dan Class_3 keduanya mewarisi Class_1.

Jika, inisialisasi Class_2 dan Class_3 dilakukan di Class_1 maka keduanya dapat memiliki nama yang berbeda di Class_2 dan Class_3 dan penggunaannya.

Ajay
sumber