Прежде всего, это поведение и лежащие в его основе рассуждения существовали всегда; В 1.9 нет ничего нового. Техническая причина, по которой это происходит, заключается в том, что main
особенный и обрабатывается иначе, чем любой другой объект. Нет никакого причудливого объяснения: он ведет себя так, потому что он был спроектирован таким образом.
Хорошо, но почему? В чем причина main
быть волшебным? Поскольку дизайнер Ruby Юкихиро Мацумото считает, что делает язык лучше , чтобы иметь такое поведение:
Это так, почему методы верхнего уровня не сделаны одноэлементными методами для этого объекта,
вместо того, чтобы тянуть в качестве методов экземпляра в классе Object
сам
(и, следовательно, во все другие классы, т. е. загрязнение пространства имен больше, чем
обычно предназначен). Это все еще позволило бы методам верхнего уровня вызывать другие
методы верхнего уровня. И если объект верхнего уровня был упомянут
немного
константа, как Main, то эти методы могут быть вызваны из любого места
с
Main.method (...).
Вы действительно хотите напечатать
"Main.print" везде?
Далее в обсуждении он объясняет, что он ведет себя так, потому что он чувствует, что «предположение естественно».
EDIT:
В ответ на ваш комментарий ваш вопрос направлен на то, почему собственный класс main, по-видимому, сообщает hello
как метод частного экземпляра. Подвох в том, что ни одна из функций верхнего уровня на самом деле не добавляется в main
, а напрямую в Object
. При работе с собственными классами семейство функций instance_methods
всегда ведет себя так, как будто собственный класс все еще является исходным классом. То есть методы, определенные в классе, обрабатываются как определенные непосредственно в собственном классе. Например:
class Object
private
def foo
"foo"
end
end
self.send :foo # => "foo"
Object.private_instance_methods(false).include? :foo # => true
self.meta.private_instance_methods(false).include? :foo # => true
class Bar
private
def bar
"bar"
end
end
bar = Bar.new
bar.send :bar # => "bar"
Bar.private_instance_methods(false).include? :bar # => true
bar.meta.private_instance_methods(false).include? :bar # => true
Однако мы можем добавить метод непосредственно к собственному классу main
. Сравните ваш оригинальный пример с этим:
def self.hello; "hello world"; end
Object.instance_methods.include? :hello # => false
self.meta.instance_methods.include? :hello # => true
Хорошо, но что, если мы действительно хотим знать, что данная функция определена в собственном классе, а не в исходном классе?
def foo; "foo"; end #Remember, this defines it in Object, not on main
def self.bar; "bar"; end #This is defined on main, not Object
foo # => "foo"
bar # => "bar"
self.singleton_methods.include? :foo # => false
self.singleton_methods.include? :bar # => true