2013-09-17 4 views
1

У меня есть условный бит кода, который может быть загружен только при определенных условиях. Это код, специфичный для платформы.Delayed require - Неинициализированная постоянная ошибка

module MyGem 
    module MyPlatformSpecificThing 
    #stuff 
    end 
end 

Моя текущая попытка лениво требует это выполняется, как:

module MyGem 
    class AClass 

    def DoSomething 
    if thing_is_true 
     require 'my_platform_specific_thing.rb' 
     MyGem::MyPlatformSpecificThing.init 
     #more stuff 
    end 
    #even more stuff 
    end 
end 

Это казалось достаточно твердый план, к сожалению, не работает. Этот код приводит к ошибке:

uninitialized constant MyGem::MyPlatformSpecificThing (NameError)

Трассировка стека указывает источник ошибки является вызов инициализации в методе DoSomething.

Я не совсем уверен, почему Ruby дает мне возможность поместиться здесь. Что я делаю неправильно, и как я должен это делать?

редактировать:

Для конкретики, я имею в виду класс платформы, расположенной here. Вышеупомянутое должно помочь сузить детали того, что я имею в виду, но в случае, если кто-то захочет/должен увидеть конкретные классы/модули, с которыми я работаю.

+0

Того, кто голосовал, чтобы закрыть этот вопрос как «неясный, как то, что задают»; Я вполне уверен, что я изложил это в вопросе, но если есть конкретный аспект этого, я могу подробно остановиться на просьбе сообщить мне об этом. –

+0

Вы можете уточнить, что проверяет 'thing_is_true'? он должен быть в экземпляре 'AClass'? Если вы можете переместить его из экземпляра, то я бы рекомендовал делать это на уровне класса, а не на уровне экземпляра. –

+0

Несомненно. Фактическая проверка проверяет переменную класса, чтобы увидеть, является ли она нулевой. Я не уверен, что я слежу за последней частью переноса требования на уровень класса, не могли бы вы подробнее рассказать об этом? –

ответ

1

У вас почти все правильно. Помните, что метод require загружается относительно пути загрузки. Когда вы создаете драгоценный камень, вы добавили каталог gem lib в путь загрузки. Изменение требует, чтобы:

require 'my_gem/bcm2835' 

Или PiPiper:

require 'pi_piper/bcm2835' 

Это необходимо загрузить только тогда, когда водитель не был установлен.

+0

Спасибо !!! https://github.com/jwhitehorn/pi_piper/commit/de359540749a587c68ef065331d0956719796553 –

+0

О нет !!!!!! После того, как я принял ваш ответ, веб-сайт повторно заказал ответы, и я случайно наградил награду неправильным «ответом» ... О, мне так плохо! Я попросил помочь мод. Надеюсь, они смогут разобраться. –

+1

lol!Не чувствую себя слишком плохо @JasonWhitehorn, я просто рад помочь :-) – orien

0

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

Отметьте этот ответ как reference.

Ваш пример показывает:

MyGem::MyPlatformSpecificThing.init 

Однако, этот формат должен иметь модуль :: Class.method. В вашем примере отображается Module :: Module.method.

Сообщение об ошибке

uninitialized constant 

очень специфичен в том, что оно распознает вызов как постоянная, а не класс.

+0

Для полноты «мой настоящий код» был связан с вопросом. Посмотрите в разделе «редактировать» внизу. - Я не уверен, что это решение на всех ... Я рассмотрю, но я уверен, что понимаю, что '::' делает ;-) –

+0

BTW, это функция уровня модуля, которую я вызываю, поэтому она 'd be Module :: Module.method ... not Module :: Class.method. –

+0

Я видел код PiPiper. И я видел, как вы его модифицировали. Я не вижу метод init. Несмотря на это, я считаю, что в определении есть проблема, которая вызывает проблему, поскольку ошибка указывает на неверную ссылку на константу. Просто пытаюсь помочь здесь, поэтому, пожалуйста, примите его в этом свете. Благодарю. –

-1

Ошибка вы указали ...

uninitialized constant MyGem::MyPlatformSpecificThing (NameError)

... будет происходить только тогда, когда внутренний модуль (PiPiper :: Bcm2835) фактически никогда не определяется; если проблема связана с фактическим вызовом функции модуля (init), вы получите другую ошибку.

Я заметил, вы закомментировал требуют от линии 10, platform.rb:

#require 'bcm2835.rb' 

... и требует файл в другом месте. Позвольте мне догадаться, это решение вашей проблемы, нет?

Взяв другой взгляд, в его первоначальной форме запрос require должен был сбой, если вы уже не добавили каталог pi_piper в $ LOAD_PATH.Попробуйте изменить ленивых требуют этого:

require './bcm2835.rb' 

Но обратите внимание, что это не будет работать, если вы измените рабочий каталог (Dir.chdir) в любой момент до выполнения этой строки.

+0

Для будущих посетителей это _NOT_ правильный ответ. Сайт переупорядочил результаты, заставляя это неправильно получать награду. –

+0

Я с радостью передам щедрость предполагаемому пользователю, если это возможно. Если вы почувствовали, что кто-то лучше ответил на этот вопрос, это зависит от вас. Но голосуете? Какую часть вы считали неправильной? – user1974458

Смежные вопросы