rake错误:"警告:已初始化常量FileUtils :: OPT_TABLE"

时间:2015-08-17 07:02:55

标签: ruby rake ruby-2.0

我已经看到有关此错误的类似问题,但所有这些都与导轨相关。我没有使用铁轨;我正在处理从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按键{。}}。

5 个答案:

答案 0 :(得分:5)

当我写require 'FileUtils'时会出现此警告。如果我写require 'fileutils'(全部小写)警告消失。

This链接可能有助于解释行为。我认为本质上ruby认为FileUtilsfileutils是不同的模块,因此导入它两次。然后,常量的重新声明会发出警告信息。

答案 1 :(得分:2)

如果有人在这里徘徊,想要清楚地回答这个问题(在被问到两年后)。

首先,请注意Ruby中的require不会加载模块,就像内存中的对象FileUtils一样。它从您的硬盘驱动器加载文件“fileutils.rb”。按惯例省略“.rb”,但您可以编写require 'fileutils.rb'

Ruby中require的目的是只加载一次文件,而不是每次使用时都重新加载文件的loadrequire避免多次加载文件的方式是记录文件名参数,如果再次传递该文件名则跳过它。

当您第一次需要文件时,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

解决