升级Thor至1.3.2后Terminal-Table报未初始化常量错误求助
解决Thor 1.3.2与Terminal-Table的命名空间冲突问题
问题背景
将Thor Gem从1.2.2升级到1.3.2后,在Thor CLI类的方法中使用Terminal-Table时触发错误:uninitialized constant Thor::Shell::Terminal::Table (NameError)。环境为Ruby 3.3.6 + macOS Homebrew,复现代码如下:
#!/usr/bin/env ruby # frozen_string_literal: true require 'bundler/inline' gemfile do source 'https://rubygems.org' gem 'thor', '1.3.2' # 1.2.2版本正常工作 gem 'terminal-table' end class TodoCLI < Thor default_task :help desc "sim", "simulation" def sim data = [ { name: 'Alice', age: 30, city: 'New York' }, { name: 'Bob', age: 25, city: 'Los Angeles' }, { name: 'Charlie', age: 35, city: 'Chicago' } ] table = Terminal::Table.new( header: %w[Name Age City], rows: data.map { |row| [row[:name], row[:age], row[:city]] } ) puts table.render end end TodoCLI.start(ARGV)
问题原因
Thor 1.3.x版本新增了Thor::Shell::Terminal模块,导致在Thor实例方法中直接引用Terminal::Table时,Ruby会优先在当前上下文(Thor::Shell::Terminal)中查找Table常量,而非顶级命名空间的Terminal::Table,从而触发未初始化常量错误。
解决方案
方案1:使用顶级命名空间限定符
直接在Terminal::Table前添加::,明确指定从Ruby顶级命名空间查找:
# 修改sim方法中的table初始化代码 table = ::Terminal::Table.new( header: %w[Name Age City], rows: data.map { |row| [row[:name], row[:age], row[:city]] } )
方案2:提前绑定顶级Terminal常量
在Thor类外部,将顶级Terminal赋值给一个自定义常量,后续在方法中使用该常量:
# 在TodoCLI类定义前添加 TERMINAL_TABLE = Terminal # 然后在sim方法中使用 table = TERMINAL_TABLE::Table.new( header: %w[Name Age City], rows: data.map { |row| [row[:name], row[:age], row[:city]] } )
内容的提问来源于stack exchange,提问作者TX T
相关产品推荐
相关产品推荐

