Как вы делаете иерархические имена классов в Ruby? - PullRequest
4 голосов
/ 06 февраля 2011

В Ruby класс с именем Foo будет определен с class Foo, использован через require 'foo' и будет жить в $:[0]/foo.rb или что-то в этом роде.

Но как насчет Foo::Bar?Будет ли он вызываться с require 'foo/bar'?Будет ли он жить в $:[0]/foo/bar.rb?И как бы это определить?

Я очень привык к Perl, где для личных проектов я бы создавал вложенные классы, такие как Project::User, Project::Text::Index, Project::Text::Search и т. Д. Затем я делал бы файлкак Project/Text/Index.pm, который начинается с package Project::Text::Index и вызывается через use Project::Text::Index;.

Сейчас я начинаю проект на Ruby и не знаю, как это сделать.По какой-то причине ни в одной из книг или документов по Ruby, которые я читал, не упоминается иерархическое именование классов в стиле perl.Когда они упоминают наследование, это обычно делается через тривиальный пример, такой как class Foo < Bar, который мне не очень помогает.Тем не менее, я полагаю, что возможно сделать то, что я пытаюсь, потому что Rails (просто для примера) имеет классы типа ActionView::Helpers::ActiveModelFormBuilder.

Ответы [ 2 ]

6 голосов
/ 06 февраля 2011

Здесь вы объединяете пару концепций, которые на самом деле не связаны, а именно путь загрузки, наследование и оператор разрешения области действия.

Когда требуется (или загружается) файл, аргумент ключевого слова require просто берется как путь к файлу и добавляется к пути поиска загрузки (расширение .rb необязательно для require). Наследование и вложение здесь не вступают в игру, и любой файл может определять все, что он хочет, например ::

require 'foo' # Looks for "foo.rb" in each of $:
require 'foo/bar' # Looks for "foo/bar.rb" in each of $:

Вложенные классы (а также модули, переменные и т. Д.) Определяются, как ожидается, но разрешаются с помощью оператора разрешения области действия, например ::

.
class Foo
  def foo; 'foo'; end
  class Bar
    def bar; 'bar'; end
  end
end
Foo.new.foo # => "foo"
Foo::Bar.new.bar # => "bar"

Обратите внимание, что вложение и наследование классов не имеют отношения к расположению файла, из которого они загружаются. Кажется, нет никаких явных соглашений для структурирования классов / модулей, так что вы можете делать то, что работает для вас. Ruby Language страница книги по программированию Ruby также может быть полезна.

3 голосов
/ 06 февраля 2011

Вам нужны модули.Если вы хотите, чтобы класс идентифицировался Funthing::Text::Index в Funthing/Text/Index.rb и требовался с require 'Funthing/Text/Index', вы делаете это:

# file Funthing/Text/Index.rb
module Funthing
  module Text
    class Index
      def do_the_twist()
        puts "Let's twist again!"
      end
    end
  end
end

Затем используйте его следующим образом:

require "Funthing/Text/Index"
c = Funthing::Text::Index.new

Примечание: файловая иерархия не требуется, но (на мой взгляд) является лучшей практикой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...