2012-07-12 21 views
5

Giả sử tôi có một phần mã Ruby nơi tôi muốn đặt bí danh một phương thức (Tôi không biết tại sao; hãy giả sử tôi có lý do chính đáng).Tôi có thể xóa bí danh phương thức trong Ruby không?

class String 
    alias_method :contains?, :include? 
end 

Nó sẽ có thể đối với tôi, sau phần này, để loại bỏ bí danh này?

Trả lời

3
def hello 
    puts "Hello World" 
end 
alias :hi :hello 

hi #=> "Hello World" 
undef hi 
hi #=> NameError 
hello #=> "Hello World" 

EDIT: Lưu ý rằng thao tác này sẽ chỉ hoạt động trên các phương thức được tạo trên đối tượng main. Để ban hành này trên một lớp, bạn sẽ cần phải làm một cái gì đó như thế nào, Hello.class_eval("undef hi")

Tuy nhiên, từ một quan điểm lập trình meta, khi giao dịch với các lớp học, tôi thích việc sử dụng remove_method :hi vì nó sẽ gây ra tra cứu phương pháp để rơi xuống và lấy phương thức từ một lớp cha.

class Nums < Array 
    def include? 
     puts "Just Kidding" 
    end 
end 

n = Nums.new 
n << 4 #=> [4] 
n.include? #=> "Just kidding" 
Nums.class_eval("remove_method :include?") 
n.include? 4 #=> true 
Number.class_eval("undef include?") 
n.include? 4 #=> NoMethodError 

remove_method thân thiện hơn nhiều.

+0

'remove_method' là tốt hơn nếu' hi' ban đầu được kế thừa hoặc kết hợp. Sử dụng 'undef' hoặc' undef_method' sẽ ngăn chặn cuộc gọi truyền bá chuỗi thừa kế/kết hợp. – Kelvin

+0

Tôi đã thực sự chỉnh sửa câu trả lời của mình để phản ánh điều đó trong khi bạn nhận xét = D –

5

remove_method sẽ hoạt động trong hầu hết các trường hợp. Nhưng nếu alias_method ghi đè phương thức hiện có, bạn có thể cần lưu bản gốc qua cuộc gọi alias_method riêng biệt.

# assuming :contains? is already a method 
alias_method :original_contains?, :contains? 
alias_method :contains?, :include? 

Sau đó, để khôi phục lại tình trạng ban đầu:

alias_method :contains?, :original_contains? 
remove_method :original_contains? # optional 

cũng Lưu ý rằng sửa đổi một lớp học đó là được sử dụng trong nhiều chủ đề là dễ bị điều kiện chủng tộc. Và nếu bạn đang cố gắng không cho phép lib sử dụng bí danh, bạn không thể ngăn chặn điều đó nếu bạn đang gọi các phương thức libs đó trong khi bí danh tồn tại. Chúng ta có thể thấy cách để làm điều này trong ruby ​​2.0: http://yehudakatz.com/2010/11/30/ruby-2-0-refinements-in-practice/

Sẽ rất hữu ích nếu bạn có thể nói lý do bạn muốn xóa bí danh. Nếu tên phương thức không tồn tại trước đó, không có libs nào khác sẽ bị ảnh hưởng bởi miếng vá khỉ của bạn. Ngoài ra, bạn nên xem xét phân lớp String (hoặc ủy quyền cho một cá thể chuỗi) thay vì vá String.

Các vấn đề liên quan