用途
loom-ruby 提供 Ruby 3.x 的语言专业知识,面向需要编写惯用且达到生产质量代码的开发者。它假设使用者已具备 Ruby 基础,重点放在容易写错的地方,例如关键字参数分离、proc 的 return 语义、对假值使用 ||=、N+1 查询、不安全反序列化、GVL,以及如何编写 loom 的 rspec 与 minitest 适配器可以逐条选中的测试。
主要能力
工具链方面,强调保留仓库已有的版本管理器与锁文件。Ruby 版本记录在 .ruby-version(rbenv、chruby、asdf、mise 读取)与 Gemfile 的 ruby 指令中。资料给出的 Bundler 常用命令包括:bundle add faraday 添加依赖;bundle add rspec --group "development, test" 添加开发/测试依赖;bundle install 从锁文件安装,并在 CI 中设置 BUNDLE_FROZEN=true 让漂移导致构建失败;bundle update --conservative faraday 保守更新单个 gem;bundle exec rspec 或 binstubs(bin/rails、bin/rspec)在 bundle 内运行;bundle exec bundler-audit check --update 检查锁文件中的已知 CVE;bundle lock --add-platform x86_64-linux 添加部署平台。bundle exec 精确激活锁定版本,裸跑 rspec 或 rake 可能加载其他已安装版本;脚本内可用 require "bundler/setup" 达到同样效果。gem 在 .gemspec 声明运行时依赖,Gemfile 放 gemspec 与开发工具。
格式与静态检查使用 RuboCop(rubocop -a 应用安全修正,-A 含不安全修正需审查 diff)或 Standard(standardrb --fix)。Rails 7.2+ 生成 bin/rubocop(rubocop-rails-omakase)与 bin/brakeman。插件有 rubocop-rspec、rubocop-performance、rubocop-rails。可用 # rubocop:disable Style/Foo ... # rubocop:enable Style/Foo 对范围禁用单个 cop,但不要对整个文件禁用全部 cop。类型检查可选:RBS(sig/*.rbs)配 Steep,或 Sorbet(# typed: strict、sig { ... }、srb tc);跟随项目已有方案,不要引入第二套。
检查门禁依次为 bundle exec rubocop(或 standardrb)、bundle exec srb tc(仅 Sorbet 项目;Steep 为 bundle exec steep check)、bundle exec rspec(或 bin/rails test、bundle exec rake test)、Rails 应用的 bundle exec brakeman --no-pager。
语言特性按版本梳理:3.0 关键字参数与位置哈希分离、case/in 模式匹配、无休止方法、Ractor(实验性)、fiber 调度器接口;3.1 哈希简写 {x:, y:}、匿名块转发、YJIT、Psych 4 使 YAML.load 默认安全;3.2 Data.define、匿名 * 与 ** 转发、Struct.new 支持关键字参数、Fiber[] 存储;3.3 内置 Prism 解析器、YJIT 提速、可选择启用的 M:N 线程调度器;3.4 it 作为隐式块参数、Prism 成为默认解析器、字符串字面量变为 chilled、Hash#inspect 输出 {name: "x"}。
内容还强调:关键字参数分离后,位置传入哈希不再变成关键字,需显式 **opts 或用 ... 转发;模式匹配无匹配分支且无 else 会抛 NoMatchingPatternError,expr => pattern 绑定或抛错,expr in pattern 返回布尔;Data.define 用于不可变值对象,with 返回修改副本;每个文件顶部加 # frozen_string_literal: true。块、Proc 与 Lambda 在元数与 return 行为上不同,超出定义方法生命周期的 proc 内 return 会抛 LocalJumpError,回调应存为 lambda;无块时应返回 Enumerator 以便链式调用。
异常部分:裸 rescue 只捕获 StandardError,不要 rescue Exception;库应定义基类错误与继承层次;rescue 中抛出会自动设置 cause;ensure 中不要 return;retry 必须用计数器限定;Timeout.timeout 可能在线程任意点中断,应改用库自带超时(Net::HTTP#read_timeout、驱动 connect_timeout、数据库 statement_timeout)。
并发部分:GVL 使同一时刻只有一个线程运行 Ruby 代码,线程只对 IO 密集任务有帮助,CPU 并行需用进程或原生扩展;Puma 以 workers×threads 运行,worker 内线程共享类级与全局可变状态,需用 Mutex#synchronize、concurrent-ruby 的 Concurrent::Map 或按请求保存状态;后台作业需参数可序列化且幂等。
Rails 要点:Zeitwerk 路径须匹配常量名,用 bin/rails zeitwerk:check 校验;N+1 用 includes/preload/eager_load,strict_loading 与 bullet 辅助;大表用 find_each/in_batches;强参数用 params.expect 或 require/permit,不要 permit!;回调限于模型自身不变量,副作用放 after_commit 或服务对象;update_column(s)、update_all、insert_all、delete_all 会跳过验证与回调;唯一性校验需配唯一索引;凭据用 bin/rails credentials:edit 或环境变量。
测试部分给出 RSpec 与 Minitest 的写法示例与要点:let 惰性且按 example 记忆,let! 每次都执行;verified doubles 会校验方法存在与元数;raise_error 应写明类名;aggregate_failures 汇总失败;随机顺序与 --seed 复现,rspec --bisect 定位顺序依赖;assert_equal 期望值在前;minitest/mock 的 stub 与 expect/verify;Rails 用 ActiveSupport::TestCase、YAML fixtures、parallelize。
loom 测试适配器:Ruby 包(kind ruby,标记为 Gemfile)由 loom project detect 选择适配器——存在 .rspec 或 Gemfile 含 rspec 时用 rspec,否则用 minitest。单测命令以包目录为 cwd:有 Gemfile 时 bundle exec rspec {file} -e '{test}',无 Gemfile 时 rspec {file} -e '{test}';minitest 为 ruby -Itest {file} -n '/^{test}$/'。test 字段:rspec 为组描述与示例描述以空格连接,嵌套描述以 #、. 或 :: 开头时与类名不加空格;minitest 为方法名。无匹配时 minitest 退出 0(0 runs),rspec 默认也报 0 examples 并退出 0,但 loom 读取摘要,零执行测试一律视为 NotSelected,契约测试值不匹配会导致 freeze 失败。契约测试文件按惯例放在 spec//*_spec.rb 与 test//*_test.rb。
适用场景
需要以 Ruby 3.x 编写生产级代码、配置 Bundler 与静态检查、排查并发与 Rails 常见陷阱、编写 RSpec/Minitest 测试,或需要与 loom 测试运行器对接单个测试的项目。
限制
资料未提供该技能的安装方式、版本号、许可、支持的 Ruby 具体小版本范围之外的信息,也未说明任何收费或价格;Loom 单测适配的 rspec 无匹配行为未捕获实际 fixture,仅依据 RSpec 文档输出实现。