Najpierw mała definicja: metoda pojedyncza to metoda zdefiniowana tylko dla pojedynczego obiektu. Przykład:
irb(main):001:0> class Foo; def method1; puts 1; end; end
=> nil
irb(main):002:0> foo = Foo.new
=> #<Foo:0xb79fa724>
irb(main):003:0> def foo.method2; puts 2; end
=> nil
irb(main):004:0> foo.method1
1
=> nil
irb(main):005:0> foo.method2
2
=> nil
irb(main):006:0> other_foo = Foo.new
=> #<Foo:0xb79f0ef4>
irb(main):007:0> other_foo.method1
1
=> nil
irb(main):008:0> other_foo.method2
NoMethodError: undefined method `method2' for #<Foo:0xb79f0ef4>
from (irb):8
Metody instancji to metody klasy (tj. Zdefiniowane w definicji klasy). Metody klasowe są pojedynczymi metodami w Class
instancji klasy - nie są zdefiniowane w definicji klasy. Zamiast tego są zdefiniowane w klasie pojedynczej obiektu.
irb(main):009:0> Foo.method_defined? :method1
=> true
irb(main):010:0> Foo.method_defined? :method2
=> false
Otwierasz pojedynczą klasę obiektu za pomocą składni class << obj
. Tutaj widzimy, że ta klasa singleton jest miejscem, w którym zdefiniowane są metody singleton:
irb(main):012:0> singleton_class = ( class << foo; self; end )
=> #<Class:#<Foo:0xb79fa724>>
irb(main):013:0> singleton_class.method_defined? :method1
=> true
irb(main):014:0> singleton_class.method_defined? :method2
=> true
irb(main):015:0> other_singleton_class = ( class << other_foo; self; end )
=> #<Class:#<Foo:0xb79f0ef4>>
irb(main):016:0> other_singleton_class.method_defined? :method1
=> true
irb(main):017:0> other_singleton_class.method_defined? :method2
=> false
Zatem alternatywnym sposobem dodawania pojedynczych metod do obiektu byłoby zdefiniowanie ich za pomocą otwartej klasy pojedynczej obiektu:
irb(main):018:0> class << foo; def method3; puts 3; end; end
=> nil
irb(main):019:0> foo.method3
3
=> nil
irb(main):022:0> Foo.method_defined? :method3
=> false
W podsumowaniu:
- metody muszą zawsze należeć do klasy (lub: być metodami instancji jakiejś klasy)
- normalne metody należą do klasy, w której są zdefiniowane (tj. są metodami instancji tej klasy)
- metody klasowe są po prostu pojedynczymi metodami klasy
Class
- metody pojedyncze obiektu nie są metodami instancji klasy obiektu; są to raczej metody instancji klasy singleton obiektu.
Ruby zapewnia sposób definiowania metod, które są specyficzne dla konkretnego obiektu, a takie metody są znane jako metody singletonowe. Kiedy ktoś deklaruje pojedynczą metodę na obiekcie, Ruby automatycznie tworzy klasę, która przechowuje tylko pojedyncze metody. Nowo utworzona klasa nosi nazwę Singleton Class.
Klasa pojedyncza to anonimowa klasa specyficzna dla obiektu, która jest automatycznie tworzona i wstawiana do hierarchii dziedziczenia.foo = Array.new def foo.size "Hello World!" end foo.size # => "Hello World!" foo.class # => Array #Create another instance of Array Class and call size method on it bar = Array.new bar.size # => 0
singleton_methods
można wywołać na obiekcie, aby uzyskać listę nazw wszystkich metod pojedynczych na obiekcie.foo.singleton_methods # => [:size] bar.singleton_methods # => []
Ten artykuł naprawdę pomógł mi zrozumieć klasy singleton w Rubim i zawiera dobry przykład kodu.
źródło
Po prostu zaktualizuj do odpowiedzi @Pistos, od wersji 1.9.2 ruby dodaj nową składnię do pobierania klasy singleton
singleton_class = ( class << foo; self; end )
można zastąpić:
https://apidock.com/ruby/Object/singleton_class
źródło
Najbardziej pragmatycznym / ukierunkowanym na działanie sposobem myślenia o tym (IMHO) jest: jako łańcuch dziedziczenia lub kolejność wyszukiwania / rozwiązywania metod. To zdjęcie może pomóc
http://www.klankboomklang.com/2007/11/25/modules-part-i-enter-the-include-class/
To jest r 1.9, kontrastujące z klasami wbudowanymi i zdefiniowanymi przez użytkownika: wciąż przetrawiam tę.
http://d.hatena.ne.jp/sumim/20080111/p1
Wydaje mi się również, że mylącym użyciem terminu jest „obiekt singletona”, co jest inną koncepcją. Obiekt singleton pochodzi z klasy, której metoda konstruktora / instancji została zastąpiona, dzięki czemu można przydzielić tylko jedną z tej klasy.
źródło
Najprościej ujmując, klasa singleton jest specjalną klasą Ruby, która łączy się z metodami hosta zdefiniowanymi na poszczególnych obiektach. W języku ruby można zdefiniować metody na poszczególnych obiektach, które są unikalne tylko dla tego obiektu. Na przykład rozważ poniższe kwestie
class User; end user = User.new def user.age "i'm a unique method" end user1 = User.new user.age #"i'm a unique method" user1.age # NoMethodError (undefined method `age' for #<User:0x0000559c66ab7338>)
Jak widać powyżej, obiekt user1 nie reaguje na metodę „age”, ponieważ jest to metoda pojedyncza, metoda jednoznacznie zdefiniowana w obiekcie użytkownika. Aby tak się stało, Ruby tworzy specjalną klasę, zwaną klasą pojedynczą lub własną, która będzie hostować tę unikalną metodę. Możesz to sprawdzić, wykonując następujące czynności:
user.singleton_class # #<Class:#<User:0x0000559c66b47c58>>
Możesz również zapytać ruby'ego, czy metoda „age” została tutaj znaleziona, używając obiektu method, aby dowiedzieć się, gdzie zdefiniowano metodę „age”. Kiedy to zrobisz, zobaczysz, że klasa singleton ma tę metodę.
user_singleton_class = user.method(:age).owner # #<Class:#<User:0x0000559c66b47c58>> user.method(:age).owner == user.singleton_class # true user_singleton_class.instance_methods(false) # [:age]
Zauważ również, że jeśli chodzi o klasę pojedynczą, metody singleton są w rzeczywistości metodami instancji.
user.singleton_methods == user_singleton_class.instance_methods(false) # true
źródło