Причина такого поведения заключается в том, что файлы Ruby читаются сверху вниз.Тела классов являются исполняемым кодом.Итак, простая причина ошибки имени в том, что интерпретатор Ruby просто еще не достиг этой части кода.
Итак, на самом деле это абсолютно допустимый код Ruby:
class Foo
puts "hello from inside a class"
end
Определение класса - это просто другое выражение.И, как и любое выражение в Ruby, оно имеет возвращаемое значение, поэтому работает следующее:
two = class Foo
def bar
end
1 + 1
end
Это становится более очевидным, когда вы используете альтернативный синтаксис для создания классов:
Foo = Class.new do
puts "Hello"
end
Единственное отличие состоит в том, что вы не вводите пространство имен, когда пишете его таким образом.
Вы уже видели такое поведение в ActiveRecord:
class Post < ActiveRecord::Base
has_many :comments
end
Здесь has_many
- этопросто вызов метода, который существует в ActiveRecord::Base
.Это будет выполнено непосредственно, когда файл загружен.Вот почему некоторые параметры has_many
и другие отношения передаются в виде строки.
class Post < ActiveRecord::Base
belongs_to :author, :class_name => "User"
end
Если бы вы упомянули сам класс User
, он поднял бы NameError
, потому чтоUser
может не загружаться при загрузке Post
.(на самом деле это не так в Rails, потому что Rails перехватывает NameErrors и пытается найти нужный файл, но это не так, как здесь).«Определение» отношения сохраняется, и только при последующем обращении к нему части будут соединяться вместе.
Модули в этом отношении абсолютно одинаковы.