2017-01-27 4 views
1

Глядя на Ruby docs, я вижу, что методы экземпляра из класса Object включены в модуль Kernel.Как класс Ruby наследуется от класса Object

Но эта линия от an article:

Класс BasicObject является родительским классом для всех классов в Ruby. Поэтому его методы доступны для всех объектов, если они явно не переопределены. До Ruby 1.9 класс Object был корнем иерархии классов. Для этого служит новый класс BasicObject, а Object - подкласс BasicObject. BasicObject - очень простой класс, практически не имеющий собственных методов. Когда вы создаете класс в Ruby, вы расширяете Object, если вы явно не укажете суперкласс, и большинству программистов никогда не понадобится использовать или расширить BasicObject.

говорит, что делает класс является расширение класса Object.

Мое знание extend заключается в том, что оно преобразует методы экземпляра, которые модуль использует в методах, которые могут быть достигнуты так же, как методы класса.

Это подразумевает здесь, что оно технически расширяется Kernel, а не включает, когда класс построен?

И как это работает, если это так?

+0

Посмотрите на [этот пост] (http://stackoverflow.com/questions/8894817/whats-the-difference-between-object-and-basicobject-in-ruby) – prashu132

+0

Спасибо Prashu. Хотя я не совсем понимаю связь с моим вопросом о том, как расширение Object работает с точки зрения модульного отношения (если это даже то, что происходит). Он просто говорит мне, что Object наследует от BasicObject, который (в основном) является чистым классом сланца. –

+0

Если вы не наследуете свой класс из любого класса, он по умолчанию наследует класс Object, который, в свою очередь, наследует класс BasicObject. Если вы наследуете класс class (кроме BasicObject), ваш родительский класс наследует класс Object и, таким образом, вы все равно остаетесь в той же иерархии Ruby. BasicObject и его подклассы (а не через Object) предоставляют вам классы классов, чтобы держаться подальше от иерархии рубинов по умолчанию, чтобы сделать вещи простыми для простого использования. – prashu132

ответ

-1

Простыми словами, Object сочетания классов с модулем ядра со стандартной доступностью методов ядра и BasicObject класс сидит не смешивается с модулем ядра с почти никакими методами, определенными в нем. Таким образом, вы должны наследовать от BasicObject непосредственно, когда вам нужен очень простой класс с простой иерархией, который остается от бремени всех методов ядра.

Если вы не наследуете какой-либо класс, он по умолчанию наследует класс Object, который, в свою очередь, наследует класс BasicObject, тем самым косвенно наследуя класс BasicObject. Когда вы наследуете класс class (кроме BasicObject), ваш родительский класс наследует класс Object, и, таким образом, вы все равно остаетесь в той же иерархии Ruby. BasicObject и его подклассы (не через Object) предоставляют вам возможность держаться подальше от иерархии рубинов по умолчанию, чтобы сделать вещи простыми для простого использования.


См. this post, вам это может пригодиться.

+1

«Простыми словами, класс Object сидит внутри ядра» - я понятия не имею, что это означает, но это, конечно, звучит неправильно. –

+0

Копирование других ответов не допускается в Stackoverflow, даже с атрибуцией. Просто ссылку на него. – akuhn

+0

Я не просто копировал, но подтверждал, что он был скопирован и предоставлен ссылка на исходное сообщение. Копирование ответа просто помогает пользователям упростить его. – prashu132

1

Большинство людей понимает extend как добавление методов класса к классу/модулю.

module Foo 
    def something 
    puts "Foo#something" 
    end 
end 

class Bar 
    extend Foo 
end 

2.3.0 :019 > Bar.something 
Foo#something 
=> nil 

Классы в Ruby на самом деле являются объектами типа Class. Итак, , когда вы используете extend модуль из класса, вы добавляете все методы экземпляра из модуля в объект класса.

Это можно сделать и на обычных объектах.

2.3.0 :020 > Bar.new.something 
NoMethodError: undefined method 'something' for #<Bar:0x007fdc220b74c0> 
2.3.0 :022 > b = Bar.new.extend Foo 
=> #<Bar:0x007fdc220bd280> 
2.3.0 :023 > b.something 
Foo#something 
=> nil 

Возвращаясь к классам с точки зрения объекта

2.3.0 :010 > Baz = Class.new 
=> Baz 
2.3.0 :011 > Baz.methods - Object.methods 
=> [] 
2.3.0 :012 > Baz.extend Foo 
=> Baz 
2.3.0 :013 > Baz.methods - Object.methods 
=> [:something] 
2.3.0 :014 > 
+0

Эта проблема возникает, когда разработчики с другого языка обращаются к рубину. – prashu132

-1

Ваше замешательство оправдано.

Это сообщение в блоге допускает терминологическую ошибку.

Они означают сказать

... При создании класса в Ruby, вы наследовать от объекта, если явно не указано супер-класса, и большинство программистов никогда не должны использовать или inherit from BasicObject.

Emphasis mine.

Вы правы, что использование «удлинения» не имеет смысла в этом контексте. Классы наследуют друг от друга, а модули могут расширять классы. Это два принципиально разных отношения!

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

Что автор хочет сказать, что

class A 
end 

автомагически предполагает

class A < Object 
end 

Надежда, разъясняющих ваше замешательство.

Если я могу порекомендовать, возможно, лучше всего получить книгу, чтобы узнать Ruby?

Книги обычно не допускают ошибок терминологии, поскольку их содержание было пересмотрено редакционной группой до публикации книги. После того, как вы освоили основы изучения языка из сообщений в блогах, это круто, так как вы сами сможете обнаружить ошибки, но, пока вы все еще набираете обороты, a book from a trusted publisher может стать вашим лучшим руководством.

+0

Почему downvote? Пожалуйста, объясните, чтобы я мог улучшить. – akuhn