【发布时间】:2023-01-19 23:17:31
【问题描述】:
我已经构建了一个 Ruby 项目,我想从使用大量 require_relative 语句切换到更智能的自动加载器,如 Zeitwerk。
项目中有很多文件/文件夹,因此我只会展示其中的一些文件/文件夹,以免让我的问题因不必要的细节而变得过于臃肿。您可以在Github 上找到整个项目。
回购的结构如下
chess/
bin/
chess
lib/
chess.rb
chess/
board.rb
serialize.rb
coordinates.rb
pieces/
(other files and folders)
(other files)
bin/chess 是可执行文件,包含
#!/usr/bin/env ruby
require "zeitwerk"
loader = Zeitwerk::Loader.for_gem
loader.setup
Chess.new.start # method that starts the whole game
lib/chess.rb 包含运行游戏逻辑的class Chess。
lib/ 内的所有其他文件都在Zeitwerk file structure 之后。
因此,lib/chess/serialize.rb包含
class Chess
module Serialize
...
end
end
和lib/chess/pieces/piece.rb包含
class Chess
module Pieces
module Piece
...
end
end
end
当我尝试运行脚本时,使用bin/chess(或cd进入bin/文件夹并运行./chess),终端返回
uninitialized constant Chess (NameError)
Zeitwerk 似乎没有加载这些文件。我阅读了他们所有的文档,但无法发现问题所在。
编辑:
正如其中一个答案所指出的,我删除了 bin/chess 中的 for_gem 调用
loader = Zeitwerk::Loader.new
loader.tag = File.basename(__FILE__, ".rb")
loader.inflector = Zeitwerk::GemInflector.new(__FILE__)
loader.push_dir("#{__dir__}/../lib")
loader.setup
但是,现在 Chess 命名空间内的所有类/模块都已加载,而位于更深目录中的所有类/模块,如 lib/chess/display/chess_display.rb(即 Chess::Display::ChessDisplay)都不会加载。
【问题讨论】: