Сумасшествие Ruby: класс против объекта?

Я только начал играть с JRuby. Это мой первый рубиновый пост. Мне было трудно понять классы и объекты в Ruby. Это не значит, что классы и объекты в других объектно-ориентированных языках. для примера

Class.is_a? Object

возвращает true и

Object.is_a? Object

слишком.

поэтому class и Object являются объектами

вот еще один

Class.is_a? Class

возвращает true и

Object.is_a? Class

слишком.

подождите, я еще не закончил

 Object.instance_of? Class
 Class.instance_of? Class

Оба являются истинными

 Object.instance_of? Object
 Class.instance_of? Object

Оба являются ложными. правильно, ничто не может быть экземпляром объекта.

И

 Class.kind_of? Class
 Object.kind_of? Class

оба истины

 Class.kind_of? Object
 Object.kind_of? Object

оба истины

Итак, оба они точно такие же, тогда почему у нас есть оба этих.?

После некоторого дополнительного копания я написал этот простой метод для возврата списка методов, поддерживаемого обоими

irb(main):054:0> def print_methods(obj)
irb(main):055:1>    obj.methods.each do |mm|
irb(main):056:2*        puts mm
irb(main):057:2>    end
irb(main):058:1> end

Единственное различие методов между print_methods (Object) и print_methods (Class) -

     Nesting

если Nesting означает наследование, Is Object похож на запечатанный класс?

Может кто-нибудь уточнить, что это такое?

Обновление: К комментарию Edds

Интересно, что я вижу много различий в списке методов в

c=Class.new
print_methods(c)

&

o=Object.new
print_methods(o)

Теперь я понимаю, что экземпляр класса действительно является экземпляром класса (и этот экземпляр класса фактически является объектом Object), а не экземпляром объекта. И даже этот экземпляр позволяет мне охватывать другие экземпляры

  xx = c.new //works - c is an Object / and xx is a instance of an Object c
  yy = o.new //nope  - o is already a instance of an Object, so it cannot be instantiated again

Итак, объект Object действительно является экземпляром класса. Поскольку

  xx.is_a? Class 

false, но

  xx.is_a? Object 

возвращает true

Am я right,??

Ответ 1

В основном ключевое значение для понимания состоит в том, что каждый класс является экземпляром класса Class, и каждый класс является подклассом Object (в 1.8 - в 1.9 каждый класс является подклассом BasicObject). Таким образом, каждый класс является объектом в том смысле, что он является экземпляром подкласса Object, т.е. Class.

Конечно, это означает, что Class является экземпляром самого себя. Если это причиняет боль мозгу, просто не думайте об этом слишком глубоко.

Object и Class являются is_a? Object

x.is_a? y возвращает true, если x.class == y or x.class < y, т.е. если класс x class y или x наследуется от y. Поскольку каждый класс наследует объект x.is_a? Object, возвращает true независимо от того, что x. (В 1.8 в любом случае в 1.9 там также BasicObject, который теперь является самым основным классом в иерархии наследования).

Они также is_a? Class

Оба Object и Class действительно являются классами, поэтому это не должно удивлять.

Они также instance_of? Class, но не instance_of? Object.

В отличие от is_a?, x.instance_of? y возвращает true, если x.class == y, а не если x.class является подклассом y. Так как оба x и y являются instance_of? Class, они не instance_of? Object.

вправо, ничего не может быть экземпляром объекта.

Это не так. Object.new.instance_of? Object истинно.

kind_of?

kind_of? является псевдонимом для is_a?, поэтому см. выше.

Итак, оба они точно такие же, тогда почему у нас есть оба этих.?

Следует отметить, что все до сих пор верно для всех классов. Например. String.is_a? Object, String.is_a? Class и String.instance_of? Class являются истинными, а String.instance_of? Object является ложным по тем же причинам, что и выше. (Также String.is_a? String и String.instance_of? String являются ложными по тем же причинам - String - это класс, а не строка).

Вы не можете заключить из этого, что все классы одинаковы. Это всего лишь экземпляры одного и того же класса.

Сравнение методов

Поскольку оба Object и Class являются классами, оба они имеют все методы экземпляра, определенные Class. Class дополнительно имеет одноэлементный метод nesting. nesting сообщает вам, какой модуль вы в настоящее время вложены, он не имеет ничего общего с наследованием.

Для любого заданного класса TheClass.methods будут возвращены методы экземпляра, определенные Class (например, superclass, который возвращает класс, на который наследуется TheClass, и new), который создает новый экземпляр TheClass) плюс методы singleton, определенные этим классом.

В любом случае methods указывает только, какие методы могут быть вызваны непосредственно на заданный объект. Он не говорит вам, какие методы могут быть вызваны на экземпляр класса. Для этого вы можете использовать instance_methods, который возвращает значительно разные результаты для Object и Class.

Ответ 2

В Ruby все это Object, включая классы и модули. Object - это самый низкоуровневый класс (ну, в Ruby 1.9.2 есть также BasicObject, но это уже другая история).

См. следующий вывод.

> Object.ancestors
# => [Object, Kernel, BasicObject] 
> Class.ancestors
# => [Class, Module, Object, Kernel, BasicObject] 
> Module.ancestors
# => [Module, Object, Kernel, BasicObject] 
> String.ancestors
# => [String, Comparable, Object, Kernel, BasicObject]

Как вы можете видеть, оба Class и Module наследуются от Object.

Вернемся к вашим первоначальным утверждениям, вам нужно понять разницу между ними

  • is_a?
  • kind_of'
  • instance_of?

Они не взаимозаменяемы. is_a? и kind_of? возвращает значение true, если другое является тем же классом или предком. И наоборот, instance_of? возвращает true только в том случае, если другое является тем же классом.

> Class.is_a? Object
# => true 
> Class.kind_of? Object
# => true 
> Class.instance_of? Object
# => false 

Ответ 3

Ramesh, в ruby ​​ все - это объект, а класс не является исключением.

попробуйте это в irb

ruby-1.9.2-p136 :001 > o = Object.new
=> #<Object:0x000001020114b0> 
ruby-1.9.2-p136 :002 > o.is_a? Class
=> false 
ruby-1.9.2-p136 :003 > o.is_a? Object
=> true 

в этом случае я создал экземпляр объекта и проверил, является ли он классом (false) или Object (true).

Класс в ruby ​​- это какой-то объект шаблона, используемый для создания экземпляров этого класса. Извините, что это не очень понятно. Основная концепция заключается в том, что ruby ​​- это чисто объектно-ориентированный язык, в отличие от Java.

Ответ 4

Иерархия класса/метакласса всегда немного озадачивает:) Просто для сравнения здесь в Smalltalk; в Ruby настройка основана на тех же принципах, за исключением того, что она не имеет различий Behavior и ClassDescription, и есть модули и eigenclasses, которые необходимо учитывать.

Полное объяснение объектной модели Smalltalk доступно в Pharo по примеру, как указано в этом связанный вопрос.

Ответ 5

Как _why пишет в в этой статье

объекты не хранят методы, только классы могут.

В первых парах раздела есть несколько полезных советов о классах vs objects

Ответ 6

Подумайте о Классах как глобальных объектах.