无法使用 fastspring-ruby API,require FastSpring 报错
结论
问题出在 gem 名称、Ruby 常量名和入口文件名的大小写不一致。FastSpring 是 Ruby 常量名,而 require 接收的是文件路径。这个库的入口文件应使用小写名称加载:
require "fastspring"
不要写成:
require "FastSpring"
在区分大小写的文件系统中,Ruby 会查找 FastSpring.rb,但 gem 实际提供的通常是 fastspring.rb,于是出现:
LoadError: cannot load such file -- FastSpring
推荐安装方式
在 Gemfile 中使用 gemspec 声明的 gem 名称,并明确指定要加载的文件:
gem "fastspring",
git: "https://github.com/FastSpring/fastspring-ruby",
require: "fastspring"
然后执行:
bundle install
如果 Bundler 根据仓库中的 gemspec 只接受原来的名称,可以保留已经能够正常安装的配置,只修改 require:
gem "FastSpring",
git: "https://github.com/FastSpring/fastspring-ruby",
require: "fastspring"
Gemfile 中 gem 名称的大小写不是重点。需要保证的是,Bundler 最终加载 fastspring,而不是 FastSpring。
在应用中加载
如果应用需要手动加载依赖,可以这样写:
require "bundler/setup"
require "fastspring"
加载完成后,代码中仍然使用库定义的 FastSpring 常量。可以先检查该常量是否存在:
require "fastspring"
puts defined?(FastSpring)
正常情况下会输出:
constant
也可以在项目目录中直接验证:
bundle exec ruby -e 'require "fastspring"; puts defined?(FastSpring)'
这里应使用 bundle exec,以确保 Ruby 从当前项目的 Bundler 环境中加载通过 Git 安装的 gem。
Rails 应用中的处理
Rails 通常会通过 Bundler 自动加载 Gemfile 中的依赖。可以直接在 Gemfile 中指定正确的加载入口:
gem "fastspring",
git: "https://github.com/FastSpring/fastspring-ruby",
require: "fastspring"
如果想自行控制加载时机,可以关闭自动加载:
gem "fastspring",
git: "https://github.com/FastSpring/fastspring-ruby",
require: false
再在 initializer 或其他需要的位置加载:
require "fastspring"
修改 Gemfile 后,重新执行:
bundle install
随后重启 Rails 进程、Spring 或应用服务器,以免旧的加载状态继续生效。
为什么手动安装后仍然报错
手动构建并安装 gem,只能解决 gem 是否已经安装的问题,不会改变 Ruby 查找文件时使用的名称。即使 gem 已经正确安装,下面的代码仍可能失败:
require "FastSpring"
因为 require 的参数对应文件名,不是 gem 名称或模块名称。正确写法仍然是:
require "fastspring"
仍然无法加载时的检查方法
先确认 Bundler 能否找到该 gem:
bundle info fastspring
如果项目使用的是大写 gem 名称,也可以尝试:
bundle info FastSpring
接着查看实际安装目录下的 lib 目录,确认其中有类似这样的入口文件:
lib/fastspring.rb
如果仓库当前版本没有在 gemspec 的 files 中包含入口文件,或者没有把 lib 设为 require_paths,才属于 gem 打包问题。即使文件存在于源码仓库中,也可能没有被放进构建后的 gem 包。
根据当前的报错和调用方式,应先把:
require "FastSpring"
改为:
require "fastspring"
这通常就是直接原因。Ruby 类和模块可以采用 FastSpring 这样的 CamelCase 命名,但对应的 require 路径不一定使用相同的大小写。
备注:内容仅供参考。
