跳至内容 跳至搜索

文件更新检查器

FileUpdateChecker 指定了 Rails 用于监视文件和控制重新加载的 API。该 API 依赖于四个方法:

  • initialize,它接受两个参数和一个块,如下所述。

  • updated?,它在文件系统有更新时返回 true,否则返回 false。

  • execute,它在初始化时执行给定的块,并更新最近监视的文件和时间戳。

  • execute_if_updated,它仅在文件被更新时执行块。

初始化后,调用 execute_if_updated 应该仅在文件系统确实发生更改时执行块。

Rails 使用此类来在每次新请求时重新加载 I18n 框架(当它们发生更改时)。

i18n_reloader = ActiveSupport::FileUpdateChecker.new(paths) do
  I18n.reload!
end

ActiveSupport::Reloader.to_prepare do
  i18n_reloader.execute_if_updated
end
方法
E
N
U

类公共方法

new(files, dirs = {}, &block)

它在初始化时接受两个参数。第一个是文件数组,第二个是可选的目录哈希。哈希必须以目录作为键,值为在该目录下监视的扩展名数组。

此方法还必须接收一个块,该块将在路径更改时被调用。在 FileUpdateChecker 初始化后,文件数组和目录列表将无法更改。

# File activesupport/lib/active_support/file_update_checker.rb, line 44
def initialize(files, dirs = {}, &block)
  unless block
    raise ArgumentError, "A block is required to initialize a FileUpdateChecker"
  end

  gem_paths = Gem.path
  @files = files.reject { |file| File.expand_path(file).start_with?(*gem_paths) }.freeze

  @globs = compile_glob(dirs)&.reject { |dir| dir.start_with?(*gem_paths) }

  @block = block

  @watched    = nil
  @updated_at = nil

  @last_watched   = watched
  @last_update_at = updated_at(@last_watched)
end

实例公共方法

execute()

执行给定的块,并更新最近监视的文件和时间戳。

# File activesupport/lib/active_support/file_update_checker.rb, line 85
def execute
  @last_watched   = watched
  @last_update_at = updated_at(@last_watched)
  @block.call
ensure
  @watched = nil
  @updated_at = nil
end

execute_if_updated()

如果文件已更新,则执行给定的块。

# File activesupport/lib/active_support/file_update_checker.rb, line 95
def execute_if_updated
  if updated?
    yield if block_given?
    execute
    true
  else
    false
  end
end

updated?()

检查是否有任何条目被更新。如果有,则监视和/或 updated_at 值将被缓存,直到通过 executeexecute_if_updated 执行块。

# File activesupport/lib/active_support/file_update_checker.rb, line 66
def updated?
  current_watched = watched
  if @last_watched.size != current_watched.size
    @watched = current_watched
    true
  else
    current_updated_at = updated_at(current_watched)
    if @last_update_at < current_updated_at
      @watched    = current_watched
      @updated_at = current_updated_at
      true
    else
      false
    end
  end
end