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

问题描述 投票:1回答:5

我已经看到有关此错误的类似问题,但所有这些都与rails有关。我没有使用铁轨;我正在研究一个从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按预期方式按键。

ruby rake ruby-2.0
5个回答
5
投票

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

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


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)的内容。


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

1
投票

我和特拉维斯有同样的问题,问题是我忘了使用bundle exec rake db:setup而不是rake db:setup。希望它可以帮助别人:)


1
投票

当我列出名为“fileutils”的宝石项目有两个版本时,我解决了类似的问题

fileutils (1.1.0, default: 1.0.2)

然后我跑了

sudo gem uninstall fileutils -v 1.1.0

并解决了

© www.soinside.com 2019 - 2024. All rights reserved.