mcpField
A
andrew-kane-gem-writer

andrew-kane-gem-writer

github.com/everyinc开发25.8k493 次安装今天更新
代码仓库

关于 andrew-kane-gem-writer

Andrew Kane Gem Writer 是一项指导 Ruby gem 结构与实现模式的技能。它强调显式 Ruby、尽量减少运行时依赖、通过钩子条件式集成 Rails,以及使用 Minitest。

主要功能

  1. 01组织 gem 入口与模块
  2. 02采用类宏 DSL 模式
  3. 03通过 ActiveSupport 钩子集成 Rails
  4. 04定义简洁的配置与错误体系
  5. 05规范 Minitest 和 gemspec

适用场景

  1. 01搭建 Ruby gem 结构
  2. 02添加可选的 Rails 集成
  3. 03检查 gem 依赖与测试

安装

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

$npx skills add https://github.com/everyinc/compound-engineering-plugin --skill andrew-kane-gem-writer

安装后在 Claude Code 中输入/andrew-kane-gem-writer确认已加载。

包含的文件

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

references/
database-adapters.md
module-organization.md
rails-integration.md
resources.md
testing-patterns.md

详细介绍

Andrew Kane Gem 编写指南

遵循 Andrew Kane 久经实战检验的模式编写 Ruby gem。他的 100 多个 gem(包括 Searchkick、PgHero、Chartkick、Strong Migrations、Lockbox、Ahoy、Blazer、Groupdate、Neighbor、Blind Index)累计下载量超过 3.74 亿次。

核心理念

简单胜于巧妙。 零依赖或尽量少用依赖。使用显式代码,而非元编程。集成 Rails,但不与 Rails 耦合。每种模式都服务于生产环境的实际需求。

入口文件结构

每个 gem 的 lib/gemname.rb 都遵循以下精确模式:

# 1. Dependencies (stdlib preferred)
require "forwardable"

# 2. Internal modules
require_relative "gemname/model"
require_relative "gemname/version"

# 3. Conditional Rails (CRITICAL - never require Rails directly)
require_relative "gemname/railtie" if defined?(Rails)

# 4. Module with config and errors
module GemName
  class Error < StandardError; end
  class InvalidConfigError < Error; end

  class << self
    attr_accessor :timeout, :logger
    attr_writer :client
  end

  self.timeout = 10  # Defaults set immediately
end

类宏 DSL 模式

Kane 的标志性模式——一次方法调用即可完成所有配置:

# Usage
class Product < ApplicationRecord
  searchkick word_start: [:name]
end

# Implementation
module GemName
  module Model
    def gemname(**options)
      unknown = options.keys - KNOWN_KEYWORDS
      raise ArgumentError, "unknown keywords: #{unknown.join(", ")}" if unknown.any?

      mod = Module.new
      mod.module_eval do
        define_method :some_method do
          # implementation
        end unless method_defined?(:some_method)
      end
      include mod

      class_eval do
        cattr_reader :gemname_options, instance_reader: false
        class_variable_set :@@gemname_options, options.dup
      end
    end
  end
end

Rails 集成

始终使用 ActiveSupport.on_load,绝不直接 require Rails gem:

# WRONG
require "active_record"
ActiveRecord::Base.include(MyGem::Model)

# CORRECT
ActiveSupport.on_load(:active_record) do
  extend GemName::Model
end

# Use prepend for behavior modification
ActiveSupport.on_load(:active_record) do
  ActiveRecord::Migration.prepend(GemName::Migration)
end

配置模式

使用 class << self 和 attr_accessor,而非 Configuration 对象:

module GemName
  class << self
    attr_accessor :timeout, :logger
    attr_writer :master_key
  end

  def self.master_key
    @master_key ||= ENV["GEMNAME_MASTER_KEY"]
  end

  self.timeout = 10
  self.logger = nil
end

错误处理

使用简单的层级结构,并提供信息丰富的消息:

module GemName
  class Error < StandardError; end
  class ConfigError < Error; end
  class ValidationError < Error; end
end

# Validate early with ArgumentError
def initialize(key:)
  raise ArgumentError, "Key must be 32 bytes" unless key&.bytesize == 32
end

测试(仅限 Minitest)

# test/test_helper.rb
require "bundler/setup"
Bundler.require(:default)
require "minitest/autorun"
require "minitest/pride"

# test/model_test.rb
class ModelTest < Minitest::Test
  def test_basic_functionality
    assert_equal expected, actual
  end
end

Gemspec 模式

尽可能不添加运行时依赖:

Gem::Specification.new do |spec|
  spec.name = "gemname"
  spec.version = GemName::VERSION
  spec.required_ruby_version = ">= 3.1"
  spec.files = Dir["*.{md,txt}", "{lib}/**/*"]
  spec.require_path = "lib"
  # NO add_dependency lines - dev deps go in Gemfile
end

应避免的反模式

  • method_missing(改用 define_method)
  • Configuration 对象(改用类访问器)
  • @@class_variables(改用 class << self)
  • 直接 require Rails gem
  • 过多的运行时依赖
  • 在 gem 中提交 Gemfile.lock
  • RSpec(改用 Minitest)
  • 繁重的 DSL(优先使用显式 Ruby 代码)

参考文件

如需了解更深入的模式,请参阅:

  • references/module-organization.md - 目录布局、方法拆分
  • references/rails-integration.md - Railtie、Engine、on_load 模式
  • references/database-adapters.md - 多数据库支持模式
  • references/testing-patterns.md - 多版本测试、CI 设置
  • references/resources.md - Kane 的代码库和文章链接

评论

支持 Markdown