2015-09-16 2 views
0

Я пишу консольную утилиту для управления проблемами Github, и я столкнулся с ошибкой undefined method.Создание всех классов в модуле доступно в модуле

Мое приложение структурирована следующим образом

gissues.rb # includes all files in subfolders 

Gissues 
    github.rb #Gissues::Github general github stuff 

    commands.rb #Gissues::commands subclass of Thor (whatisthor.com), general command stuff 

    cli.rb #subclass of commands, lists command shortcuts and subcommands 

    commands 

     user.rb #Command::User subclass of Gissues::Commands holds logic for github user related commands like signin, signout, whoami 

    github 

     user.rb #Github::User subclass of Gissues::Github holds logic for communicating with github for authentication (checking credentials) 

я определил методы для общения с Github в user.rb внутри папки GitHub. Я хочу использовать эти методы в user.rb, определенные в папке команд, но когда я это делаю, он кажется вне области видимости, и я получаю метод, не определяемый ошибкой.

user.rb (команды) выглядит следующим образом

module Gissues 
    class Command::User < Gissues::Command 
     desc "signin", "Starts loging sequence" 
     def signin 
      Gissues::Github::User::request_token 
     end 
    end 
end 

, и я получаю следующее сообщение об ошибке

/Users/someone/RubymineProjects/Gissues/lib/gissues/commands/user.rb:9:in `signin': undefined method `request_token' for Gissues::Github::User:Class (NoMethodError) 

Что я делаю неправильно? Заранее спасибо

Edit: This image may make the structure more clear Это изображение может сделать структуру более ясной

+1

Вы можете явно указать 'require_relative '../ github/user'' или вам нужно проверить, что' github/user' требуется * перед * 'command/user' в верхнем файле. – mudasobwa

ответ

0

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

Типичный модуль выглядит следующим образом:

module Gissues 
    require 'gissues/command' 
    require 'gissues/user' 
end 

Они должны быть перечислены в порядке их зависимости. Возможно, хотя и не рекомендуется использовать autoload для выполнения той же задачи.

До тех пор, пока все они загружены в правильном порядке, вы должны быть хорошими.

Следует отметить, что методы следует называть Gissues::Github::User.request_token с точкой перед методом. Обозначение :: обычно зарезервировано для имен классов или констант, таких как Gissues::CONST против Gissues.method_name.

+0

Вызов 'require', как это вводит в заблуждение; это делает его похожим на то, что он каким-то образом связан с «Gissues». 'require' просто запускает код в файле. Период. Это ничего не значит. Поэтому гораздо яснее ставить вызовы 'require' на верхнем уровне, а не внутри выражения модуля или класса. –

+0

@ JörgWMittag Это вопрос предпочтения, они могут идти в конце файла. Поскольку они оцениваются на немедленной основе, конечный результат тот же. Обратите внимание, что выражение 'require' не может находиться в верхней части файла здесь, поскольку эти подмодули могут зависеть от определения' Gissues'. То, как у меня здесь, невозможно ошибиться. – tadman

+0

В этом случае он может находиться в конце файла на верхнем уровне или непосредственно после выражения определения модуля на верхнем уровне. В StackOverflow есть много вопросов, в которых проблема заключается в том, что OP предполагает, что вызов вызова 'require' внутри выражения определения модуля каким-то образом охватит код в файле внутри модуля. Таким образом, это кажется распространенным заблуждением и просто никогда не пишет вызов 'require' внутри выражения определения модуля, помогает бороться с этим заблуждением. Вот почему я вообще стараюсь избегать этого. –