【问题标题】:rake error: "warning: already initialized constant FileUtils::OPT_TABLE"rake 错误:“警告:已初始化常量 FileUtils::OPT_TABLE”
【发布时间】:2015-08-17 07:02:54
【问题描述】:

我看到过有关此错误的类似问题,但都是与 rails 相关的。我没有使用导轨;我正在处理一个本地 rake 任务,该任务从 yaml 文件中读取,然后对数据进行处理。我宁愿不为此安装 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


    【解决方案1】:

    当我写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)。

      【讨论】:

      • 一年后,这肯定会派上用场。我在我的项目目录中搜索“fileutils”,果然我的一个文件需要FileUtils,而其他文件需要fileutils。谢谢!!!
      【解决方案3】:

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

      fileutils (1.1.0, default: 1.0.2)
      

      然后我跑

      sudo gem uninstall fileutils -v 1.1.0
      

      解决了

      【讨论】:

        【解决方案4】:

        我发现如果我只是注释掉或删除原始代码 (require 'FileUtils') 的第 1 行,这些警告不会出现并且脚本可以完美运行。虽然我没有浏览过 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
        

        【讨论】:

        • 在我的情况下 zip 已经包含 FileUtils,我认为在 ruby​​ 中使用了类似于 C 的东西,以避免多次包含?
        【解决方案5】:

        我对 Travis 也有同样的问题,问题是我忘记使用 bundle exec rake db:setup 而不是 rake db:setup。希望它可以帮助某人:)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-09-24
          • 1970-01-01
          • 1970-01-01
          • 2021-07-04
          • 2011-01-02
          • 2011-08-29
          • 2011-11-29
          • 2014-07-25
          相关资源
          最近更新 更多