2012-07-12 9 views
5

Załóżmy Mam sekcji kodu Ruby gdzie chciałbym aliasu metodę (nie wiem dlaczego, niech po prostu Załóżmy, że mam dobry powód).Czy mogę usunąć alias metody w Ruby?

class String 
    alias_method :contains?, :include? 
end 

byłoby możliwe dla mnie, po tym rozdziale, aby usunąć ten alias?

Odpowiedz

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

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

EDYCJA: Należy zauważyć, że działa to tylko na metodach utworzonych na obiekcie main. Aby wykonać to na zajęciach, musisz zrobić coś takiego, jak:, Hello.class_eval("undef hi")Jednak z punktu widzenia metaprogramowania, w kontaktach z klasami, lubię korzystanie z remove_method :hi, ponieważ spowoduje to przeszukiwanie metody do upaść i pobrać metodę z klasy nadrzędnej.

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 jest znacznie bardziej przyjazny meta.

+0

'remove_method' jest lepsze, jeśli' hi' był pierwotnie dziedziczony lub zmieszany. Użycie 'undef' lub' undef_method' uniemożliwi rozmowom propagowanie łańcucha dziedziczenia/łączenia. – Kelvin

+0

Naprawdę edytowałem swoją odpowiedź, aby odzwierciedlić to, gdy skomentowałeś = D –

5

remove_method powinny działać w większości przypadków. Ale jeśli alias_method nadpisuje istniejący sposób, może być konieczne, aby zachować oryginalne poprzez oddzielny alias_method rozmowy.

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

Następnie w celu przywrócenia pierwotnego stanu:

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

Należy również zauważyć, że zmiana klasy, który jest używany w wielu wątków jest podatna na wyścig warunki. A jeśli próbujesz uniemożliwić używanie bibliotek przez alias, nie możesz temu zapobiec, jeśli wywołujesz metody tych bibliotek, gdy istnieje alias. Możemy zobaczyć, jak to zrobić w Ruby 2.0: http://yehudakatz.com/2010/11/30/ruby-2-0-refinements-in-practice/

Byłoby pomocne, gdybyś mógł powiedzieć, dlaczego chcesz usunąć alias. Jeśli nazwa metody nie istniała wcześniej, żadna inna biblioteka nie powinna być dotknięta łatą małpy. Ponadto powinieneś rozważyć podklasowanie String (lub delegowanie do instancji łańcucha znaków) zamiast łatania String.

Powiązane problemy