Agent skill

Ruby

by ericrisco in ericrisco/rsc-harness

A skill your agent uses when writing or refactoring plain Ruby outside Rails — scripts, CLIs, gems, libraries: Enumerable chains and blocks, module mixins and value objects, Bundler/gemspec…

MITAuto-check passedDevelopment

Install Ruby

skills CLI
$ npx skills add ericrisco/rsc-harness --skill ruby -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install ericrisco/rsc-harness ruby --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/ruby .claude/skills/ruby && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
ruby
GitHub stars
156
Token cost
~3.2k tokens
SKILL.md length
1,136 words
Files
6 (incl. scripts, references)
Skills in repo
229
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when writing or refactoring plain Ruby outside Rails — scripts, CLIs, gems, libraries: Enumerable chains and blocks, module mixins and value objects, Bundler/gemspec…

  • Works in 6 steps: Everything is an expression and returns… → Everything is an object receiving… → Reach for Enumerable before you write a… → …
  • Refactoring plain Ruby outside Rails — scripts
  • SKILL.md covers Mental model, Blocks, procs, lambdas, yield, Enumerable & Comparable and Modules & composition, plus 7 more sections
  • Runs Shell scripts from its folder; calls bundle and gem

What it does

Ruby is an agent skill from ericrisco/rsc-harness. Use when writing or refactoring plain Ruby outside Rails — scripts, CLIs, gems, libraries: Enumerable chains and blocks, module mixins and value objects, Bundler/gemspec packaging, whether metaprogramming earns its keep, Minitest or RSpec, Ruby 3.4/4.0 frozen-string hygiene. NOT Rails, ActiveRecord, or ActiveSupport idioms (that is rails).

Its SKILL.md is about 3.2k tokens, which your agent loads only when the skill is triggered. The skill folder holds 8 other files, including scripts and reference files (for example `evals/README.md`, `evals/cases.yaml` and `references/gems-and-testing.md`).

It sits in Development, covering Backend development, ORMs and data access and Refactoring. It works with Ruby and Ruby on Rails. The repository describes itself as: Your agent invents things because it has no memory, and can't touch your database because it has no arms. rsc is the meta-harness that gives it both, plus the trade to know the… The licence is MIT.

When your agent uses it

  • Refactoring plain Ruby outside Rails — scripts
  • Libraries: Enumerable chains and blocks
  • Module mixins and value objects
  • Bundler/gemspec packaging

Example prompts

  • “/ruby”

Requirements

  • A Bash shell

Workflow steps

6 steps, taken from the first numbered list in SKILL.md.

  1. Everything is an expression and returns a value. if, case, blocks, method
  2. Everything is an object receiving messages. 5.times, nil.to_a, "x".freeze.
  3. Reach for Enumerable before you write a loop. A manual index loop in Ruby is
  4. Prefer returning new values to mutating in place. Mutation is allowed but it is
  5. Freeze your string literals. New files start with # frozen_string_literal: true.
  6. Dynamism is the trap, not the feature. Metaprogramming is a scalpel; if a plain

What it can do on your machine

Read from SKILL.md and the folder at commit 92fde8f. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 1 file in scripts/ (Shell), which the agent can run.

    Shell commands in SKILL.md call:

    • bundle
    • gem

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Ruby loads about 3.2k tokens when it runs, and up to ~5.9k if it reads all its reference files. Until then it costs about 87 tokens; SKILL.md has 1,136 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~87
When it runs · the whole SKILL.md, loaded when a task matches
~3.2k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~5.9k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from ericrisco/rsc-harness at commit 92fde8f, republished under its MIT licence (© ericrisco). 1,136 words, ~3,180 tokens.

Download SKILL.mdSave it as .claude/skills/ruby/SKILL.md (or your agent's skills folder). This skill also uses 5 other files; get the full folder from GitHub.
name
ruby
description
Use when writing or refactoring plain Ruby outside Rails — scripts, CLIs, gems, libraries: Enumerable chains and blocks, module mixins and value objects, Bundler/gemspec packaging, whether metaprogramming earns its keep, Minitest or RSpec, Ruby 3.4/4.0 frozen-string hygiene. NOT Rails, ActiveRecord, or ActiveSupport idioms (that is `rails`).
tags
ruby, gems, bundler, metaprogramming, rspec, minitest, enumerable
recommends
rails, testing-web, secure-coding
origin
risco

Idiomatic Ruby, the language

Write Ruby a senior Rubyist would sign off on: expression-oriented, block-driven, leaning on Enumerable and Comparable instead of hand-rolled loops, with frozen_string_literal hygiene and a real Gemfile/.gemspec when you package.

This is Ruby the language and its non-Rails ecosystem — blocks, modules, gems, metaprogramming, Minitest/RSpec. Delegate: Rails apps, ActiveRecord models, controllers, migrations, views, Hotwire — anything that loads Rails or uses ActiveSupport/ActiveRecord idioms — to rails; the same task in another language to python, go, rust, elixir, php or typescript; the CI pipeline that runs your Ruby tests to github-actions — this skill writes the tests, not the workflow.

Targets Ruby 4.0 (released 2025-12-25) on 3.4 semantics: Prism is the default parser, string literals warn on mutation without a magic comment, it is an implicit block param, and Set is now a core class.

Mental model

Internalize these before writing a line:

  1. Everything is an expression and returns a value. if, case, blocks, method bodies all yield a value — name and return it instead of threading a flag.
  2. Everything is an object receiving messages. 5.times, nil.to_a, "x".freeze. There are no primitives to special-case.
  3. Reach for Enumerable before you write a loop. A manual index loop in Ruby is almost always a map/select/reduce you have not spotted yet.
  4. Prefer returning new values to mutating in place. Mutation is allowed but it is the exception you justify, not the default.
  5. Freeze your string literals. New files start with # frozen_string_literal: true.
  6. Dynamism is the trap, not the feature. Metaprogramming is a scalpel; if a plain method, a Struct, or a Data does the job, use that.

Blocks, procs, lambdas, yield

Blocks are the spine of Ruby. A method takes a block implicitly via yield, or explicitly with &block when it must store or forward it.

ruby
# frozen_string_literal: true

# Implicit: yield runs the caller's block and returns its value.
def with_timing
  start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  result = yield
  [result, Process.clock_gettime(Process::CLOCK_MONOTONIC) - start]
end

# Explicit: capture the block as a Proc to forward or store it.
def retrying(times, &block)
  attempts = 0
  begin
    block.call
  rescue StandardError
    (attempts += 1) < times ? retry : raise
  end
end

proc vs lambda differ in two ways that bite:

Aspectproc / blocklambda / ->
ArityLenient — extra args dropped, missing become nilStrict — wrong count raises ArgumentError
returnReturns from the enclosing method (can surprise)Returns from the lambda only

Rule: use a lambda for a function-like value you call yourself; use a block/proc for the "do this with each element" pattern. For cheap accumulation prefer each_with_object (returns the seed) or reduce; use tap (returns the receiver) for side effects and then for piping a value through a transform.

ruby
# Bad: index loop building a result by mutation.
result = []
(0...items.length).each { |i| result << items[i].upcase if items[i].size > 3 }

# Good: intent reads top-to-bottom, no index, no pre-seeded array.
result = items.select { |s| s.size > 3 }.map(&:upcase)

Enumerable & Comparable

Most loops map to one named method. Pick by intent, not by habit:

You want to…Use
Transform every elementmap
Keep / drop by predicateselect / reject
Fold into one valuereduce / sum / min_by
Build a Hash or accumulate into a seedeach_with_object
Count occurrencestally
Bucket by a keygroup_by
First matchfind (detect)
Pair index with elementeach_with_index

Make your own classes first-class collections by including Enumerable and defining each; get <, >, between?, clamp, sort for free by including Comparable and defining <=>.

ruby
# frozen_string_literal: true

class Playlist
  include Enumerable

  def initialize(tracks) = @tracks = tracks
  def each(&) = @tracks.each(&)   # one method unlocks map/select/sort/...
end

class Version
  include Comparable
  attr_reader :major, :minor

  def initialize(major, minor)
    @major = major
    @minor = minor
  end

  def <=>(other) = [major, minor] <=> [other.major, other.minor]
end

Modules & composition

Ruby favors composition through mixins over deep inheritance.

  • include M — adds M's instance methods to instances (the default mixin).
  • prepend M — inserts M before the class in the lookup chain, so M's methods can wrap the originals via super (cleaner than aliasing for decoration).
  • extend M — adds M's methods as class/singleton methods.

Rule: reach for a module mixin when the same behavior is shared across unrelated classes; reserve inheritance for a genuine is-a hierarchy. Namespace with module Foo to avoid global constant clashes. Need to patch a class without polluting it globally? Use a refinement (refine … using) — a scoped, reversible scalpel — never a bare monkey-patch. Full refinement scoping and prepend-wrapping in references/metaprogramming.md.

Value objects: Data vs Struct

ruby
# frozen_string_literal: true

Point  = Data.define(:x, :y)         # immutable value object (Ruby 3.2+)
origin = Point.new(x: 0, y: 0)       # no setters; with(x: 1) returns a copy

Cursor = Struct.new(:x, :y)          # mutable; has setters and is Enumerable
NeedReach for
Immutable value with equality + withData.define
Mutable record, or array/positional accessStruct.new

Default to Data for value semantics; pick Struct only when you genuinely need mutation or positional/to_a behavior.

Metaprogramming, sparingly

Decision rule, in order: could a plain method, a Struct, or a Data do this? If yes, do that. Only when the method names themselves are dynamic (driven by data or config) does metaprogramming earn its keep.

  • Prefer define_method (defines real, introspectable methods) over method_missing (intercepts at call time, slower, invisible to respond_to? and tooling).
  • If you must use method_missing, you must also define respond_to_missing? — otherwise respond_to?, method, and duck-typing all lie about your object.
  • Never eval a string built from user input.
ruby
# Good: dynamic method names, but real methods that introspect and document themselves.
class Config
  def initialize(**data) = @data = data

  %i[host port timeout].each do |key|
    define_method(key)       { @data[key] }
    define_method("#{key}=") { |value| @data[key] = value }
  end
end

Building a real DSL, instance_eval/class_eval, and the full method_missing + respond_to_missing? pairing live in references/metaprogramming.md.

Show full SKILL.md (415 more words)Show less

Gems & Bundler

Bundler is the universal dependency manager. bundle init creates a Gemfile; bundle install resolves and writes Gemfile.lock; run project binaries with bundle exec so they use the locked versions.

  • Use the pessimistic constraint ~> 2.3 (allows 2.x >= 2.3, blocks 3.0) for libraries; pin tighter only when forced.
  • Commit Gemfile.lock for applications (reproducible installs); for a library gem, do not commit the lock — let consumers resolve.
  • Scaffold a gem with bundle gem NAME, which generates the lib/, test//spec/, .gemspec, and Rakefile layout.
ruby
# my_gem.gemspec
Gem::Specification.new do |spec|
  spec.name        = "my_gem"
  spec.version     = MyGem::VERSION       # SemVer: MAJOR.MINOR.PATCH
  spec.summary     = "One-line description."
  spec.authors     = ["You"]
  spec.files       = Dir["lib/**/*.rb"]
  spec.required_ruby_version = ">= 3.4"
  spec.add_dependency "thor", "~> 1.3"
end

Full bundle gem tree, publishing flow (gem build / gem push), and Rake test tasks are in references/gems-and-testing.md.

Ruby 4.0 / 3.4 hygiene

ruby
# frozen_string_literal: true     # without it, 3.4+ warns under -W:deprecated on mutation

nums.map { it * 2 }               # `it` is the implicit single block param (3.4+)
seen = Set.new([1, 2, 3])         # Set is a core class in 4.0 — no `require "set"`
  • The magic comment freezes every string literal in the file; mutating one then raises FrozenError. This is the cause of most "my string froze after upgrading" reports.
  • it reads cleaner than _1 for one-arg blocks.
  • Ruby 4.0 ships ZJIT (a new JIT written in Rust, successor to YJIT) and removed Ractor.yield/Ractor#take in favor of Ractor::Port.

Testing

Both ship a clean path; choose by ceremony tolerance:

FrameworkPick when…
MinitestYou want the default — ships with Ruby, tiny surface, assert-style or spec-style, fast.
RSpecYou want the expressive DSL and large ecosystem (describe/context/it/expect, let, mocks).
ruby
# test/tally_test.rb  (Minitest)
require "minitest/autorun"
require "tally"

class TallyTest < Minitest::Test
  def test_counts_words
    assert_equal({ "a" => 2, "b" => 1 }, Tally.count("a b a"))
  end
end
ruby
# spec/tally_spec.rb  (RSpec)
RSpec.describe Tally do
  subject(:counts) { described_class.count("a b a") }
  it { is_expected.to eq("a" => 2, "b" => 1) }
end

Run via bundle exec rake test (Minitest) or bundle exec rspec (RSpec). Fuller examples with let/subject/context are in references/gems-and-testing.md.

Linting & typing (optional layers)

  • Linter: Standard (zero-config, "no bikeshadding" wrapper) when you want one less argument; RuboCop (.rubocop.yml, every cop opt-in/out) when the team wants control.
  • Types: two coexisting systems — RBS (official signatures in separate .rbs files, checked by Steep) and Sorbet (inline sig blocks, with experimental inline-RBS-comment support). Add types only on a library's public surface or a hot, bug-prone core — not on throwaway scripts. RuboCop vs Standard config sits in references/gems-and-testing.md.

Anti-patterns

Anti-patternWhy it bitesDo instead
Monkey-patching a core class globallyAction-at-a-distance; collides with gems and future RubyA refinement (scoped) or a wrapper/helper
method_missing without respond_to_missing?respond_to?/method/duck-typing all liePair them, or prefer define_method
Mutating a frozen string literalFrozenError after the magic commentdup before mutating, or build a new string
for x in coll loopsLeaks the loop var; un-idiomaticcoll.each/map/select
rescue Exception (bare)Swallows SignalException, NoMemoryError, exitrescue StandardError (or specific classes)
Not committing Gemfile.lock for an appNon-reproducible installs across machinesCommit it for apps; omit only for library gems
eval of user-derived inputRemote code executionParse explicitly; never eval untrusted data
Over-DSLing config a Hash would serveHidden control flow, slow method_missingA plain Hash or Data object

© ericrisco, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 5 other files (scripts, references) in skills/ruby of ericrisco/rsc-harness.

  • SKILL.md
  • evals/README.md
  • evals/cases.yaml
  • references/gems-and-testing.md
  • references/metaprogramming.md
  • scripts/verify.sh

Open the folder on GitHubat commit 92fde8f

Compare with similar skills

Ruby next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Ruby compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Ruby this skillericrisco/rsc-harness156—~3.2kAutomated safety check: PassMIT
Antipattern Preventiondoorkeeper-gem/doorkeeper5.5k—~1.1kAutomated safety check: PassMIT
Ruby Patternssoftspark/ai-toolkit179—~2.3kAutomated safety check: PassApache-2.0
Ruby Rulessoftspark/ai-toolkit179—~3.4kAutomated safety check: PassApache-2.0
Rails Hotwirepproenca/dot-skills214—~2.3kAutomated safety check: PassMIT
Ruby Optimisepproenca/dot-skills214—~1.7kAutomated safety check: PassMIT

Similar skills

  • Antipattern Prevention

    doorkeeper-gem/doorkeeper

    Avoid common Ruby and Rails antipatterns that degrade maintainability and performance.

    5.5k GitHub stars~1.1k tokensUpdated yesterday
    Backend & APIsAuto-check passed
  • Ruby Patterns

    softspark/ai-toolkit

    Ruby/Rails: blocks, metaprogramming, ActiveRecord, Sidekiq, RSpec, Sorbet, Hanami.

    179 GitHub stars~2.3k tokensUpdated today
    Backend & APIsAuto-check passed
  • Ruby Rules

    softspark/ai-toolkit

    Ruby coding rules: style, patterns, security, testing. An agent skill from softspark/ai-toolkit.

    179 GitHub stars~3.4k tokensUpdated today
    Backend & APIsAuto-check passed
  • Rails Hotwire

    pproenca/dot-skills

    Ruby on Rails Hotwire best practices for building interactive applications with Turbo Drive, Turbo Frames, Turbo Streams, Turbo 8 morphing, and Stimulus controllers.

    214 GitHub stars~2.3k tokensUpdated 1 mo ago
    Backend & APIsAuto-check passed
  • Ruby Optimise

    pproenca/dot-skills

    Ruby performance optimization guidelines. An agent skill from pproenca/dot-skills.

    214 GitHub stars~1.7k tokensUpdated 1 mo ago
    DevelopmentAuto-check passed
  • Rails Expert

    Jeffallan/claude-skills

    Builds Rails 7+ apps with Hotwire Turbo Frames and Streams, Active Record tuning, Action Cable, Sidekiq jobs and RSpec specs, with migration and N+1 checks.

    12k GitHub stars~1.4k tokensUpdated 4 days ago
    Backend & APIsAuto-check passed

More from ericrisco/rsc-harness

All 229 skills in this repo
  • Ab Testing

    ericrisco/rsc-harness

    A skill your agent uses when designing or analyzing a controlled experiment — falsifiable hypothesis, sample size from an MDE, reading significance/CI/power, CUPED, or rescuing tests that won't go…

    156 GitHub stars~2.4k tokensUpdated yesterday
    Auto-check passed
  • Accessibility

    ericrisco/rsc-harness

    A skill your agent uses when making a web UI conform to WCAG 2.2 Level AA — axe-core or Lighthouse a11y violations, keyboard operability, focus management, ARIA roles/names/live regions, contrast…

    156 GitHub stars~3.4k tokensUpdated yesterday
    Auto-check passed
  • Ads

    ericrisco/rsc-harness

    A skill your agent uses when running or fixing paid acquisition on Google or Meta — campaign structure (Performance Max, Demand Gen, Search, Advantage+), platform-fit creative, budget/scaling rules…

    156 GitHub stars~2.2k tokensUpdated yesterday
    Auto-check passed
  • Agent Eval

    ericrisco/rsc-harness

    A skill your agent uses when measuring whether an LLM or agent system actually got better and gating merges on it: golden sets, fixing an inflated LLM-as-judge, scoring RAG (faithfulness, contextual…

    156 GitHub stars~3.2k tokensUpdated yesterday
    Auto-check passed
  • AI Media

    ericrisco/rsc-harness

    A skill your agent uses when a creative goal must become a finished media file: pick and order generative-media models per modality — AI voiceover, image-to-video clips, score — then glue them with…

    156 GitHub stars~3.3k tokensUpdated yesterday
    Auto-check passed
  • Analytics

    ericrisco/rsc-harness

    A skill your agent uses when instrumenting product or web analytics — GA4/PostHog SDK wiring, event taxonomy, funnels, double-counted events, consent gating, PII scrubbing.

    156 GitHub stars~2.8k tokensUpdated yesterday
    Auto-check passed

Questions about Ruby

What does Ruby do?

A skill your agent uses when writing or refactoring plain Ruby outside Rails — scripts, CLIs, gems, libraries: Enumerable chains and blocks, module mixins and value objects, Bundler/gemspec…. Ruby is an agent skill from ericrisco/rsc-harness.0 frozen-string hygiene.

When should I use Ruby?

Ruby fits situations like: refactoring plain Ruby outside Rails — scripts; libraries: Enumerable chains and blocks; module mixins and value objects; bundler/gemspec packaging.

How do I install Ruby in Claude Code?

Run `npx skills add ericrisco/rsc-harness --skill ruby -a claude-code`. Or copy the skill folder (skills/ruby in ericrisco/rsc-harness) into .claude/skills/ruby in your project. Claude Code loads it when a task matches its description.

How do I install Ruby in Codex?

Run `npx skills add ericrisco/rsc-harness --skill ruby -a codex`. Or copy the skill folder (skills/ruby in ericrisco/rsc-harness) into .agents/skills/ruby in your project. Codex loads it when a task matches its description.

Can I use Ruby in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ericrisco/rsc-harness --skill ruby -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/ruby, .gemini/skills/ruby, .github/skills/ruby and .opencode/skills/ruby in your project.

What does Ruby need to run?

Going by SKILL.md and its folder, Ruby needs a shell for the scripts in its folder and the command-line tools its instructions call (bundle and gem). Our summary lists: A Bash shell.

Does Ruby access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Ruby safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does Ruby use?

Ruby is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Ruby use?

About 3.2k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 2.7k tokens, read only when the agent opens those files.

What are the alternatives to Ruby?

Skills that share tags, products or a category with Ruby: Antipattern Prevention (doorkeeper-gem/doorkeeper, 5.5k stars), Ruby Patterns (softspark/ai-toolkit, 179 stars), Ruby Rules (softspark/ai-toolkit, 179 stars) and Rails Hotwire (pproenca/dot-skills, 214 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Ruby?

ericrisco (a GitHub user) maintains it in ericrisco/rsc-harness, which has 156 GitHub stars. The repository holds 229 skills in this directory. The repository was last updated on October 6, 2026.

Source: ericrisco/rsc-harness on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.