如何进行第二次请求

24

有没有一种方法可以强制再次require加载文件?

我正在编写一个位于Ruby路径中的库。在使用IRB简单测试时,我同时编辑这个文件。

每次我更改文件时,我希望重新加载它而不结束IRB会话。使用load需要每次键入整个文件路径,而每次重新启动IRB都需要输入所有其他变量设置,这些变量是进行简单测试所需的。

我想要像require一样的东西,但允许第二次加载。有没有简单的方法可以实现?


你只能使用 IRB 吗?你可以使用 pry 吗? - Darek Nędza
3个回答

32

load不需要(嗯)完整的路径。它期望一个带有扩展名的完整文件名。

p load 'date.rb' #=> true
p load 'date.rb' #=> true
p load 'date'    #=> LoadError

我知道是否有“.rb”之间的区别,但不知为何我没有意识到路径的问题。 - sawa

4
你可以编写自己的代码并将其放在.irbrc文件中: 新热点
module Kernel
  def reload(lib)
    if old = $LOADED_FEATURES.find{|path| path=~/#{Regexp.escape lib}(\.rb)?\z/ }
      load old
    else
      require lib
    end
  end
end

分钟级别的缓存已经失效

module Kernel
  # Untested
  def reload(lib)
    if File.exist?(lib)
      load lib
    else
      lib = "#{lib}.rb" unless File.extname(lib)=='.rb'
      $:.each do |dir|
        path = File.join(dir,lib)
        return load(path) if File.exist?(path)
      end
    end
  end
end

对于旧版本,如果你想支持RubyGems,你需要使它更加健壮。
这些解决方案的一个问题是,虽然它们会强制重新加载相关文件,但如果该文件反过来调用其他文件(通常是gem的情况),那些文件将不会被重新加载。
解决这个问题会非常丑陋。也许需要手动进入$LOADED_FEATURES数组,并删除所有与gem名称相关的路径。

我已经编辑了答案,包括利用现有的 require 魔法的简化版本。 - Phrogz
感谢您的帮助。实际上,我的问题可能有点愚蠢。正如steenslag所回答的那样,我可能根本不必担心路径的问题。但是您的代码将会很有用。 - sawa

4
:000> path = "extremely/long/path/to/my/file"
:001> load path
:002> load path

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接