Что именно представляет собой одноэлементный класс в ruby?
Вопрос
Является ли класс singleton в Ruby классом сам по себе?Является ли это причиной, по которой все объекты принадлежат "классу"? Концепция заключается в нечеткий, но я считаю , что это как - то связано с тем, почему я вообще могу определить метод класса (class foo; def foo.bar ...
).
Что такое одноэлементный класс в Ruby?
Решение
Во-первых, небольшое определение: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
Таким образом, альтернативным способом добавления одноэлементных методов к объекту было бы определить их с помощью одноэлементного класса объекта 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
Подводя итог:
- методы всегда должны принадлежать классу (или:быть методами экземпляра некоторого класса)
- обычные методы принадлежат классу, в котором они определены (т. е.являются методами экземпляра класса)
- методы класса - это просто одноэлементные методы
Class
- одноэлементные методы объекта не являются методами экземпляра класса объекта;скорее, они являются методами экземпляра одноэлементного класса объекта.
Другие советы
Ruby предоставляет способ определения методов, специфичных для конкретного объекта, и такие методы известны как одноэлементные методы.Когда для объекта объявляется одноэлементный метод, Ruby автоматически создает класс для хранения только одноэлементных методов.Вновь созданный класс называется Singleton Class.
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, и у него есть хороший пример кода.
Как только обновите ответ @Pistos, начиная с версии 1.9.2, ruby добавит новый синтаксис для получения одноэлементного класса
singleton_class = ( class << foo; self; end )
может быть заменен на:
singleton_class = foo.singleton_class
Наиболее прагматичный / ориентированный на действие способ думать об этом (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 р>
Кроме того, я полагаю, что вводящее в заблуждение использование термина - это " Singleton object " ;, что является другим понятием. Одноэлементный объект происходит из класса, у которого переопределен метод конструктора / экземпляра, так что вы можете выделить только один из этого класса.