Rozważ następującą klasę:
class Foo
def an_inst_method
'instance method'
end
def self.a_class_method
'class method'
end
alias_method :a_new_inst_method, :an_inst_method
end
To nie jest problem i możesz dzwonić Foo.new.a_new_inst_method
bez problemu.
Chciałbym mieć możliwość posiadania metody klasowej Foo.add_widget(*items)
i aliasu, aby móc zrobić coś takiego:
Foo.add_widget 'item1'
Foo.add_widgets 'item2', 'item3'
Więc w zasadzie nie ma „Ruby stylu” jak 1.minute
i 2.minutes
tak chcę alias a Foo.add_widget
więc wywołanie Foo.add_widgets
wywołuje dokładnie te same metody. Wiem, że mógłbym to owinąć, ale wydaje mi się, że powinienem móc to zrobić w czystszy sposób.
Rozważ moją próbę wypróbowania czegoś takiego:
class Foo
def an_inst_method
'instance method'
end
def self.a_class_method
'class method'
end
alias_method :a_new_inst_method, :an_inst_method
alias_method :a_new_class_method, :a_class_method
end
Jednak pojawia się następujący błąd:
NameError (undefined method `a_class_method' for class `Foo')
I wygląda na to, że to nie działa w przypadku metod klasowych. Jak mam to zrobić?
źródło
extend ClassMethods
rozwiązaniu. +1Ważną rzeczą do zrozumienia jest to, że w Ruby nie istnieje metoda klasowa .
Metoda klasowa jest tak naprawdę tylko metodą singleton. Nie ma nic specjalnego w metodach klasowych. Każdy obiekt może mieć metody singleton. Po prostu nazywamy je „metodami klasowymi”, gdy obiekt jest,
Class
ponieważ „metoda singletonowa instancjiClass
” jest zbyt długa i niewygodna.Czekać! Czy powiedziałem „singleton method”?
Inną ważną rzeczą do zrozumienia jest to, że nie ma czegoś takiego jak metoda singleton w Ruby.
Metoda singleton jest tak naprawdę zwykłą nudną, starą metodą instancji klasy singleton. Nie ma nic specjalnego w metodach singleton. Są to tylko metody instancji, jak każda inna metoda instancji.
W rzeczywistości Ruby ma tylko metody instancji. Bez funkcji, bez konstruktorów, bez metod statycznych, bez metod klasowych, bez funkcji modułowych, bez metod singletonowych.
Pytanie nie brzmi „czy jest to metoda klasowa, czy jest to metoda singletonowa”, ale raczej „w którym module jest zdefiniowana ta metoda?”
„Metody singletonowe” to tak naprawdę metody instancji zdefiniowane w klasie singleton. Składnia dostępu do klasy singleton
foo
toIstnieje również metoda,
Object#singleton_class
która zwraca klasę singleton obiektu.Dlaczego tak agresywnie zastanawiam się nad tym, że każda metoda jest metodą instancji, a metody klas nie istnieją? Ponieważ oznacza to, że model obiektowy Ruby jest o wiele prostszy, niż ludzie myślą! W końcu w swoim pytaniu pokazujesz już, że wiesz, jak aliasować metody instancji, ale mówisz, że nie wiesz, jak aliasować metody klas. Ale to źle! Ci zrobić wiedzieć jak alias metod klasy, ponieważ one są tylko metody instancji . Jeśli zostałeś właściwie nauczony tego faktu, nigdy nie musiałbyś zadawać tego pytania!
Gdy zrozumiesz, że każda metoda jest metodą instancji i że to, co nazywamy „metodami singleton”, jest tylko metodami instancji klasy singleton, rozwiązanie staje się jasne:
Uwaga: kiedy napisałem powyżej, że „nie ma czegoś takiego jak X”, miałem na myśli to, że „nie ma czegoś takiego jak X w języku Ruby ”. To nie znaczy, że te koncepcje nie istnieją w społeczności Ruby .
Regularnie mówimy o „metodach singletonowych” i „metodach klasowych”, po prostu dlatego, że jest to łatwiejsze niż mówienie o „metodach instancji klasy singletonów” lub „metodach instancji klasy singletonów obiektu, który przypadkiem jest instancją
Class
klasy „. Istnieją nawet metody, takie jakObject#define_singleton_method
,Object#singleton_method
,Object#singleton_methods
,Module#private_class_method
,Module#public_class_method
, iModule#module_function
w podstawowej bibliotece Ruby. Zawsze jednak należy pamiętać, że nie są to pojęcia językowe. Są to koncepcje społeczności , które istnieją tylko w naszych głowach i nazwach niektórych metod bibliotecznych.źródło
OK, wygląda na to, że mogę zrobić coś takiego i zadziała:
Jeśli ktoś ma tutaj jakieś przydatne informacje na temat języka Ruby i chce udzielić wyczerpującej odpowiedzi, dam +1.
źródło
class << self
, a następniealias_method :a_new_class_method, :a_class_method
rzeczywiście zadzwonićalias_method
na singleton klasyFoo
. Innym sposobem pisania tego jest:singleton_class.alias_method :a_new_class_method, :a_class_method
w kontekście klasowym.alias_method
działa na instancji, więc musisz zejść o jeden poziom głębiej i operować naClass
instancji lub metaklasie klasy . Ruby ma model dzikiego obiektu, który może trochę łamać mózg, ale daje też mnóstwo mocy:źródło