Что такое класс singleton в ruby?
кажется, что я упускаю суть или неправильно понимаю значение класса singleton в Ruby. Я слышал и читал об этом во многих отношениях-некоторые более сложные, чем другие,-но я больше запутался в том, что это такое. Это класс сам по себе? Это причина, почему все объекты принадлежат к " классу?"Понятие нечеткие, но я считаю, что это как-то связано с тем, почему я могу определить метод класса вообще (класс foo; def foo.бар... ).
Итак: Что это одноэлементный класс в Ruby?
4 ответа:
во-первых, небольшое определение: a синглтон метод - это метод, который определяется только для одного объекта. Пример:
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
методы экземпляра-это методы класса (т. е. определенные в определении класса). Методы класса-это одноэлементные методы на
Class
экземпляр класса-они не определены в определении класса. Вместо этого, они определяются на синглтон класс объекта.irb(main):009:0> Foo.method_defined? :method1 => true irb(main):010:0> Foo.method_defined? :method2 => false
открыть одноэлементный класс объекта с синтаксисом
class << obj
. Здесь мы видим, что этот одноэлементный класс-это то, где определены одноэлементные методы: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
таким образом, альтернативным способом добавления одноэлементных методов к объекту было бы определить их с помощью класса singleton объекта open:
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
в итоге:
- методы всегда должны принадлежать классу (или: быть методами экземпляра некоторого класса)
- нормальные методы принадлежат классу они определены в (т. е. являются методами экземпляра класса)
- методы класса-это просто одноэлементные методы a
Class
- синглтон-методы объекта не являются методами экземпляра класса объекта; скорее, они являются методами экземпляра Singleton-класс объекта.
Ruby предоставляет способ определения методов, специфичных для конкретного объекта, и такие методы известны как одноэлементные методы. Когда объявляется одноэлементный метод для объекта, Ruby автоматически создает класс для хранения только одноэлементных методов. Вновь созданный класс называется Одноэлементным классом.
Одноэлементный класс-это анонимный класс, специфичный для объекта, который автоматически создается и вставляется в иерархию наследования.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
можно вызвать на объект, чтобы получить список имен всех синглтон-методы объекта.foo.singleton_methods # => [:size] bar.singleton_methods # => []
этой статьи действительно помог мне понять одноэлементные классы в Ruby, и у него есть хороший пример кода.
наиболее прагматичный / действенный способ думать об этом (IMHO): как цепочка наследования или порядок поиска/разрешения метода. Эта картина может помочь
http://www.klankboomklang.com/2007/11/25/modules-part-i-enter-the-include-class/
Это r 1.9, контрастирующие встроенные и пользовательские классы: я все еще перевариваю этот.
http://d.hatena.ne.jp/sumim/20080111/p1
кроме того, я думаю, что запутанный использование термина "одноэлементный объект", который является другим понятием. Одноэлементный объект происходит из класса, который имеет переопределенный метод конструктора/экземпляра, так что вы можете выделить только один из этого класса.