mcpField
R
ruby

ruby

github.com/midudev开发7.0k56 次安装2 周前更新
代码仓库

关于 ruby

这项技能提供 Ruby 3.x 及更高版本的惯用写法与约定,面向开发者和编码 Agent,涵盖错误处理、现代语言特性、性能及代码组织。

主要功能

  1. 01异常与结果对象模式
  2. 02Ruby 3.x 语言特性
  3. 03注重性能的枚举处理
  4. 04安全的记忆化与字符串构建
  5. 05方法排序与文件布局

适用场景

  1. 01为预期失败选择处理约定
  2. 02使用现代 Ruby 语法和模式
  3. 03提升枚举与字符串构建效率
  4. 04组织 Ruby 类中的方法

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/midudev/autoskills --skill ruby

安装后在 Claude Code 中输入/ruby确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
error_handling.md
method_ordering.md
modern_ruby.md
ood-philosophy.md
performance.md

详细介绍

Ruby 语言技能

概述

一套注重实践的 Ruby 约定与惯用写法,用于编写符合 Ruby 3.x+ 惯例的代码。重点关注 Agent 默认容易忽略的模式——Weirich 的 raise/fail 区分、可安全处理 nil 的记忆化、预期失败时使用结果对象而非异常,以及注重性能的枚举方式。

错误处理约定

Weirich raise/fail 约定

首次抛出异常时使用 fail,仅在重新抛出时使用 raise:

def process(order)
  fail ArgumentError, "Order cannot be nil" if order.nil?

  begin
    gateway.charge(order)
  rescue PaymentError => e
    logger.error("Payment failed: #{e.message}")
    raise  # re-raise with raise
  end
end
自定义异常层次结构

将领域异常归入一个基类错误:

module MyApp
  class Error < StandardError; end
  class PaymentError < Error; end
  class InsufficientFundsError < PaymentError; end
end

# Rescue at any granularity:
rescue MyApp::InsufficientFundsError  # specific
rescue MyApp::PaymentError            # category
rescue MyApp::Error                   # all app errors
使用结果对象处理预期失败

对于预期的失败路径,使用结果对象而非异常:

class Result
  attr_reader :value, :error
  def self.success(value) = new(value: value)
  def self.failure(error) = new(error: error)
  def initialize(value: nil, error: nil) = (@value, @error = value, error)
  def success? = error.nil?
  def failure? = !success?
end
由调用方提供备用处理方式

通过代码块让调用方定义错误处理方式:

def fetch_user(id, &fallback)
  User.find(id)
rescue ActiveRecord::RecordNotFound => e
  fallback ? fallback.call(e) : raise
end

user = fetch_user(999) { |_| User.new(name: "Guest") }

完整模式与重试策略请参阅 references/error_handling.md。

现代 Ruby(3.x+)

模式匹配
case response
in { status: 200, body: { users: [{ name: }, *] } }
  "First user: #{name}"
in { status: (400..), error: message }
  "Error: #{message}"
end

# Find pattern
case array
in [*, String => str, *]
  "Found string: #{str}"
end

# Pin operator
expected = 200
case response
in { status: ^expected, body: }
  process(body)
end
其他 3.x+ 特性
# Endless methods (3.0+)
def square(x) = x * x
def admin? = role == "admin"

# Numbered block parameters (2.7+)
[1, 2, 3].map { _1 * 2 }

# Data class - immutable value objects (3.2+)
Point = Data.define(:x, :y)
p = Point.new(x: 1, y: 2)
p.with(x: 3)  # => Point(x: 3, y: 2)

# Hash#except (3.0+)
params.except(:password, :admin)

# filter_map (2.7+) - select + map in one pass
users.filter_map { |u| u.email if u.active? }

# tally (2.7+)
%w[a b a c b a].tally  # => {"a"=>3, "b"=>2, "c"=>1}

Ractor、Fiber 调度器、RBS 类型和高级模式匹配请参阅 references/modern_ruby.md。

性能快速优化

冻结字符串字面量
# frozen_string_literal: true
# Add to top of every file. Prevents mutation, reduces allocations.
# When you need mutable: String.new("hello") or +"hello"
高效枚举
# each_with_object for building results (avoids intermediate arrays)
totals = items.each_with_object(Hash.new(0)) do |item, hash|
  hash[item.category] += item.amount
end

# Lazy enumerables for large/infinite sequences
(1..Float::INFINITY).lazy.select(&:odd?).map { _1 ** 2 }.first(10)
记忆化的 nil/false 注意事项
# Simple (only works if result is truthy)
def users = @users ||= User.all.to_a

# Safe (handles nil/false results)
def feature_enabled?
  return @feature_enabled if defined?(@feature_enabled)
  @feature_enabled = expensive_check
end
字符串构建
# Bad: O(n^2) with +=
result = ""; items.each { |i| result += i.to_s }

# Good: O(n) with <<
result = String.new; items.each { |i| result << i.to_s }

# Best: join
items.map(&:to_s).join

YJIT、GC 调优、基准测试和性能分析工具请参阅 references/performance.md。

优先采用的 Ruby 惯用写法

守卫子句
def process(value)
  return unless value
  return unless value.valid?
  # main logic here
end
字面量数组构造器
STATES = %w[draft published archived]      # word array
FIELDS = %i[name email created_at]         # symbol array
使用 Hash#fetch 获取必需键
config.fetch(:api_key)                     # raises KeyError if missing
config.fetch(:timeout, 30)                 # default value
config.fetch(:handler) { build_handler }   # lazy default
安全导航
user&.profile&.avatar_url  # returns nil if any link is nil
谓词与 Bang 约定
  • ? 后缀:返回布尔值(empty?、valid?、admin?)
  • ! 后缀:危险版本——会修改接收者,或在失败时抛出异常(save!、sort!)
  • 定义 Bang 方法时,始终提供一个非 Bang 版本作为替代

方法排序与文件布局

按从上到下的顺序组织类,让读者每次只需深入一个抽象层级——即“逐步深入”/报纸式布局。元素顺序如下:

  1. extend / include / prepend
  2. 常量
  3. attr_* 读写方法与类宏(has_many、validates、scope)
  4. def initialize
  5. 公有方法——从最高层级的入口开始
  6. protected
  7. private 辅助方法——按抽象层级分组

在公有区块和私有区块内,均按抽象层级由广到窄排序,而不是按调用方进行深度优先排序。 将同一抽象层级的方法与其同级方法放在一起,然后排列它们调用的辅助方法,再排列这些辅助方法所调用的方法。将辅助方法紧接着唯一的调用方定义,会打散高层步骤,并将它们埋在细节之下。

# Good — breadth-first by altitude: stages cluster, then their helpers
def process; validate; charge; notify; end   # altitude 1 (public entry)

private

def validate; end                            # altitude 2: stages together
def charge;   end
def notify;   end

def verify_customer; end                      # altitude 3: helpers together
def submit_payment;  end
def write_audit_log; end

# Bad — depth-first by caller: altitudes 2 and 3 interleave, stages scatter
def validate;        end
def verify_customer; end
def charge;          end
def submit_payment;  end
def notify;          end
def write_audit_log; end

示例、逐步深入/SLAP 背景说明以及共享辅助方法的放置方式请参阅 references/method_ordering.md。

常见错误

错误修正
对新异常使用 raise使用 fail;仅在重新抛出时使用 raise(Weirich 约定)
结果可能为 nil/false 时使用 @var ||= compute改用 defined?(@var) 检查
在循环中使用 += 拼接字符串使用 << 或 .join——+= 的复杂度为 O(n²)
rescue Exception捕获 StandardError——Exception 也会捕获 SignalException、NoMemoryError
过深的 &. 链(3 个或更多链接)提取为方法,或使用显式 nil 检查
缺少 # frozen_string_literal: true添加到每个文件的顶部
将辅助方法紧接着唯一的调用方定义(深度优先)按抽象层级对方法分组;采用由广到窄的布局(逐步深入规则)

参考资料

  • references/modern_ruby.md - 模式匹配、Ractor、Fiber 调度器、RBS 类型
  • references/error_handling.md - 异常层次结构、结果对象、重试模式
  • references/performance.md - YJIT、GC 调优、基准测试、性能分析
  • references/ood-philosophy.md - OOD 原则、命名、SOLID、TRUE 启发式、迪米特法则
  • references/method_ordering.md - 文件布局顺序、逐步深入规则、由广到窄与深度优先的方法排序

评论

支持 Markdown