2015-08-17 6 views
1

Я видел похожие вопросы относительно этой ошибки, но все они связаны с рельсами. Я не пользуюсь рельсами; Я работаю над локальной задачей rake, которая читает из файла yaml, а затем обрабатывает данные. Я бы предпочел не устанавливать пакет для этого (решения для подобных проблем с рельсами предполагают добавление bundle exec), так как этот скрипт прост и, следовательно, не нуждается в нем.ошибка рейка: «предупреждение: уже инициализированная константа FileUtils :: OPT_TABLE»

Вот упрощенный код (который получает такую ​​же ошибку, как код, я работаю):

require 'FileUtils' 
require 'yaml' 

SOME_FILE = "#{Dir.pwd}/some_file.yaml" 

task default: :foo 

task :foo do 
    bar = File.open(SOME_FILE) { |yf| YAML::load(yf) } 
    bar.each {|k,v| puts k} 
end 

А вот список ошибок:

/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/FileUtils.rb:93: warning: already initialized constant FileUtils::OPT_TABLE 
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/fileutils.rb:93: warning: previous definition of OPT_TABLE was here 
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/FileUtils.rb:1272: warning: already initialized constant FileUtils::Entry_::S_IF_DOOR 
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/fileutils.rb:1272: warning: previous definition of S_IF_DOOR was here 
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/FileUtils.rb:1535: warning: already initialized constant FileUtils::Entry_::DIRECTORY_TERM 
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/fileutils.rb:1535: warning: previous definition of DIRECTORY_TERM was here 
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/FileUtils.rb:1537: warning: already initialized constant FileUtils::Entry_::SYSCASE 
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/fileutils.rb:1537: warning: previous definition of SYSCASE was here 
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/FileUtils.rb:1656: warning: already initialized constant FileUtils::LOW_METHODS 
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/fileutils.rb:1656: warning: previous definition of LOW_METHODS was here 
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/FileUtils.rb:1662: warning: already initialized constant FileUtils::METHODS 
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/fileutils.rb:1662: warning: previous definition of METHODS was here 

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

ответ

1

Я обнаружил, что эти предупреждения не отображаются, и сценарий работает отлично, если я просто закомментирую или удаляю строку 1 моего исходного кода (require 'FileUtils'). Хотя я не просматривал код для Rake, он должен уже включать FileUtils (что имеет смысл).

Для полноты картины, вот мой пересмотренный код (обратите внимание, что я удалил require 'FileUtils' строки:.

require 'yaml' 

SOME_FILE = "#{Dir.pwd}/some_file.yaml" 

task default: :foo 

task :foo do 
    bar = File.open(SOME_FILE) { |yf| YAML::load(yf) } 
    bar.each {|k,v| puts k} 
end 
+0

В моем случае zip уже включает FileUtils, я думал, что в рубине было использовано нечто похожее на C, чтобы избежать множественного включения? –

5

Это предупреждение появляется, когда я пишу require 'FileUtils' Если я пишу require 'fileutils' (все строчные) предупреждение исчезает.

This ссылка может быть полезным объяснить поведение. Я думаю, в сущности рубин думает FileUtils и fileutils различные модули, поэтому импортирует его в два раза. Тогда переопределение констант дают предупреждающие сообщения.

1

У меня была та же проблема с Тревисом, и проблема в том, что я забыл использовать bundle exec rake db:setup вместо rake db:setup. Надеюсь, это поможет кому-то :)

0

Требуется ответить на это ясно (через два года после его запроса) на случай, если кто-то бродит здесь.

Во-первых, обратите внимание, что require в Ruby не загружает модуль, как в объекте FileUtils, который находится в памяти. Он загружает файл «fileutils.rb» с вашего жесткого диска. «.rb» опускается по соглашению, но вы можете написать require 'fileutils.rb'.

Целью require в Ruby является загрузка файла только один раз, в отличие от load, который будет перезагружать файл каждый раз, когда он будет использоваться. Способ require позволяет избежать загрузки файла несколько раз, записав аргумент имени файла и пропустив его, если он, если это имя файла снова передается.

Когда вы сначала требуете файла, Ruby отвечает true, чтобы указать, что он был загружен.Если вам требуется один и тот же файл снова вернет ложь, чтобы показать, что он уже загружен:

> require 'fileutils' 
=> true 
> require 'fileutils' 
=> false 

Поскольку имя файла, запасенной require чувствителен к регистру, но фактический поиск файла нет, fileutils.rb еще будут найдены если вы используете заглавные буквы в названии:

> require 'FileUtils' 
=> true 

Но если что-то в вашей программе Ruby, уже загружен файл без колпачков (в вашем случае «yaml.rb», вероятно, требует «FileUtils» а) вы будете перезагружать файл и может видеть предупреждения:

> require 'fileutils' 
=> true 
> require 'FileUtils' 
/bin/ruby/lib/ruby/2.3.0/FileUtils.rb:96: warning: already initialized constant FileUtils::OPT_TABLE 
etc. 

По соглашению Рубиновые файлы должны быть названы в нижнем регистре с символами подчеркивания, например. «my_class.rb», поэтому вы всегда будете использовать require 'my_class'.

Все становится немного сложнее, если вам требуется использование абсолютных или относительных путей, например. require 'special_classes/my_class'. Я предлагаю прочитать около require_relative и путь загрузки Ruby ($LOAD_PATH).