Что именно представляет собой одноэлементный класс в ruby?

StackOverflow https://stackoverflow.com/questions/212407

  •  03-07-2019
  •  | 
  •  

Вопрос

Является ли класс 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

https://apidock.com/ruby/Object/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 " ;, что является другим понятием. Одноэлементный объект происходит из класса, у которого переопределен метод конструктора / экземпляра, так что вы можете выделить только один из этого класса.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top