2011-01-21 73 views
317

Tôi đã tìm thấy bài đăng trên blog trên aliasalias_method. Như được hiển thị trong ví dụ được đưa ra trong bài đăng trên blog đó, tôi chỉ muốn đặt bí danh một phương thức cho một phương thức khác trong cùng một lớp. Tôi nên sử dụng cái nào? Tôi luôn thấy alias được sử dụng, nhưng ai đó đã nói với tôi alias_method thì tốt hơn.Tôi có nên sử dụng bí danh hoặc alias_method không?

Sử dụng bí danh

class User 

    def full_name 
    puts "Johnnie Walker" 
    end 

    alias name full_name 
end 

User.new.name #=>Johnnie Walker 

Sử dụng alias_method

class User 

    def full_name 
    puts "Johnnie Walker" 
    end 

    alias_method :name, :full_name 
end 

User.new.name #=>Johnnie Walker 

Blog post link here

+4

Bài đăng đó không trả lời câu hỏi của bạn phải không? – marcog

+3

@marcog: Tôi đã đọc qua và tôi không bị thuyết phục. Định nghĩa các bí danh bên trong các phương thức, đó không phải là điều mà một người nên làm thường xuyên. –

+2

@digitalextremist link works –

Trả lời

355

alias_method có thể được định nghĩa lại nếu cần thiết. (nó được định nghĩa trong lớp Module.)

alias thay đổi hành vi tùy thuộc vào phạm vi của nó và đôi khi có thể không thể đoán trước được.

Bản án: Sử dụng alias_method - giúp bạn linh hoạt hơn.

Cách sử dụng:

def foo 
    "foo" 
end 

alias_method :baz, :foo 
+39

Bạn có ý nghĩa gì bởi không thể đoán trước. Ngớ ngẩn, người ta sẽ nói rằng tùy chọn ít linh hoạt hơn sẽ dễ dự đoán hơn. Ngoài ra, bạn có thể cung cấp bất kỳ ví dụ thực tế nào về việc hưởng lợi từ việc xác định lại alias_method không? –

+22

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

+7

ví dụ về trường hợp sử dụng: 'alias: new_method_name: old_method_name' OR' alias_method: new_method_name,: old_method_name' –

30

Một điểm ủng hộ alias thay vì alias_method là ngữ nghĩa của nó được công nhận bởi rdoc, dẫn đến tài liệu tham khảo chéo gọn gàng trong tài liệu được tạo ra, trong khi rdoc hoàn toàn bỏ qua alias_method.

+54

Có lẽ RDoc nên bắt đầu điều trị alias_method giống như bí danh. Chúng ta nên nói với họ về điều đó;) –

+9

Hoàn toàn đồng ý. Yard xử lý điều này khá tốt nếu tôi nhớ chính xác ... –

+16

Một lý do nữa để sử dụng [Yardoc] (http://yardoc.org/) thay cho RDoc. – iain

-18

Mặc dù nó có thể là nhỏ, nhưng có hai điều tôi thích về bí danh, nhiều hơn so với alias_method:

(1) bí danh ngắn

(2) Bạn không có để nhập,

Điều này rất ít, tôi biết, nhưng khi bạn thực hiện việc này vài trăm lần trong nhiều năm, bạn chỉ có xu hướng thích bí danh bất cứ khi nào có thể

+10

Tôi đã tự hỏi tại sao điều này có quá nhiều downvotes và không phải là một bình luận. Sau khi đọc, tôi biết tại sao. – DickieBoy

33

Tôi nghĩ rằng có một quy tắc bất thành văn (một cái gì đó giống như quy ước) nói rằng sử dụng 'bí danh' chỉ để đăng ký bí danh tên phương thức, có nghĩa là nếu bạn muốn cung cấp cho người dùng mã của bạn một phương thức có nhiều hơn một tên:

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

Nếu bạn cần mở rộng mã của mình, hãy sử dụng thay thế 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 
16

Một năm sau khi yêu cầu câu hỏi đặt ra một bài viết mới về đề tài này:

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

Dường như "rất nhiều nam giới, rất nhiều suy nghĩ." Từ tác giả bài viết trước đây khuyến khích sử dụng alias_method, trong khi tác giả thứ hai đề xuất sử dụng alias.

Tuy nhiên có một cái nhìn tổng quan chung của các phương pháp này trong cả hai blogposts và câu trả lời ở trên:

  • sử dụng alias khi bạn muốn hạn chế răng cưa với phạm vi mà nó định nghĩa
  • sử dụng alias_method để cho phép các lớp kế thừa để truy cập nó
36

Ngoài các cú pháp, sự khác biệt chính là trong Phạm vi:

# 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 #=> 'Gekky geek' 

Trong phương thức "tên" ở trên, hãy chọn phương thức "full_name" được xác định trong lớp "Nhà phát triển". Bây giờ, hãy thử với 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' 

Với cách sử dụng bí danh, phương thức "tên" không thể chọn phương thức "full_name" được xác định trong Nhà phát triển.

Điều này là do alias là một từ khóa và nó được lexically scoped. Nó có nghĩa là nó xử lý self là giá trị của tự tại thời điểm mã nguồn được đọc. Ngược lại, alias_method xử lý self làm giá trị được xác định tại thời gian chạy.

Nguồn: http://blog.bigbinary.com/2012/01/08/alias-vs-alias-method.html

0

này bây giờ được xử lý trong Ruby Style Guide:

thích bí danh khi các phương pháp khử răng cưa trong phạm vi lớp học từ vựng như độ phân giải tự trong bối cảnh này cũng là từ vựng, và nó giao tiếp rõ ràng với người dùng rằng việc chuyển hướng bí danh của bạn sẽ không bị thay đổi trong thời gian chạy hoặc bởi bất kỳ lớp con nào trừ khi thực hiện rõ ràng.

class Westerner 
    def first_name 
    @names.first 
    end 

alias given_name first_name 
end 

Luôn luôn sử dụng alias_method khi aliasing phương pháp mô-đun, lớp học, hoặc lớp singleton lúc chạy, như phạm vi từ vựng của bí danh dẫn đến không thể tiên đoán trong những trường hợp

module Mononymous 
    def self.included(other) 
    other.class_eval { alias_method :full_name, :given_name } 
    end 
end 

class Sting < Westerner 
    include Mononymous 
end 
Các vấn đề liên quan