我已经看到有关此错误的类似问题,但所有这些都与导轨相关。我没有使用铁轨;我正在处理从yaml文件读取的本地rake任务,然后处理数据。我不想为此安装bundler(针对类似rails问题的解决方案建议使用bundle exec
),因为这个脚本很简单,因此不需要它。
这里是简化代码(它与我正在处理的代码有相同的错误):
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
按键{。}}。
答案 0 :(得分:5)
当我写require 'FileUtils'
时会出现此警告。如果我写require 'fileutils'
(全部小写)警告消失。
This链接可能有助于解释行为。我认为本质上ruby认为FileUtils
和fileutils
是不同的模块,因此导入它两次。然后,常量的重新声明会发出警告信息。
答案 1 :(得分:2)
如果有人在这里徘徊,想要清楚地回答这个问题(在被问到两年后)。
首先,请注意Ruby中的require
不会加载模块,就像内存中的对象FileUtils
一样。它从您的硬盘驱动器加载文件“fileutils.rb”。按惯例省略“.rb”,但您可以编写require 'fileutils.rb'
。
Ruby中require
的目的是只加载一次文件,而不是每次使用时都重新加载文件的load
。 require
避免多次加载文件的方式是记录文件名参数,如果再次传递该文件名则跳过它。
当您第一次需要文件时,Ruby会以true响应以指示它已加载。如果您再次需要相同的文件,它将返回false以指示它已被加载:
> 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.
按照惯例,Ruby文件应以小写形式命名,并带有下划线,例如: “my_class.rb”,所以你总是使用require 'my_class'
。
如果您要求使用绝对路径或相对路径,事情变得有点棘手,例如: require 'special_classes/my_class'
。我建议阅读require_relative
和Ruby加载路径($LOAD_PATH
)。
答案 2 :(得分: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
答案 3 :(得分:1)
我遇到了与Travis相同的问题,问题是我忘记使用bundle exec rake db:setup
而不是rake db:setup
。希望它可以帮助某人:)
答案 4 :(得分:1)
当我列出名为“ fileutils”的gem项目有两个版本时,我解决了类似的问题
fileutils (1.1.0, default: 1.0.2)
然后我跑步
sudo gem uninstall fileutils -v 1.1.0
解决