mcpField
A
andrew-kane-gem-writer

andrew-kane-gem-writer

github.com/everyinc開発25.8k493 回インストール今日更新
リポジトリ

andrew-kane-gem-writer について

Andrew Kane Gem Writerは、Andrew Kaneのプロジェクトで説明されているパターンに沿ってRuby gemを構成するスキルです。明示的なRuby、最小限の実行時依存、フック経由のRails連携、Minitestを重視します。

主な機能

  1. 01gemのエントリーポイントとモジュールの構成
  2. 02クラスマクロDSLパターンの利用
  3. 03ActiveSupportフックによるRails連携
  4. 04簡潔な設定とエラー体系の定義
  5. 05Minitestとgemspecの規約

活用シーン

  1. 01Ruby gemの構成開始
  2. 02任意のRails連携の追加
  3. 03gemの依存関係とテストの確認

インストール

コマンドをコピーしてターミナルで実行します。

$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 Writer

374M 回以上ダウンロードされている 100 個以上の gem(Searchkick、PgHero、Chartkick、Strong Migrations、Lockbox、Ahoy、Blazer、Groupdate、Neighbor、Blind Index)で実証されている Andrew Kane のパターンに従って、Ruby gem を作成します。

基本理念

巧妙さよりシンプルさを優先します。 依存関係はゼロまたは最小限にします。メタプログラミングより明示的なコードを優先します。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 を象徴するパターンです。1 回のメソッド呼び出しですべてを設定します。

# 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 を使用し、Rails の gem を直接 require しないでください。

# 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

設定パターン

Configuration オブジェクトではなく、attr_accessor を使った class << self を使用します。

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 を使用します)
  • Rails の gem を直接 require すること
  • 実行時の依存関係を多数追加すること
  • 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 のリポジトリや記事へのリンク

コメント