Language-specific super-code guidelines for ruby.
Scanned 9/2/2026
Install to Claude Code
npx -y skills add sickn33/agentic-awesome-skills --skill ruby --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Ruby?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/sickn33-ruby)More formats (shields.io, HTML) on the badges page.
---
name: ruby
description: "Language-specific super-code guidelines for ruby."
risk: safe
source: community
date_added: "2026-06-16"
---
# Ruby: Idiomatic Efficiency Reference
## When to Use
- Use this skill when the task matches this description: Language-specific super-code guidelines for ruby.
## Table of Contents
1. [Enumerable & Collections](#enumerable)
2. [Blocks, Procs & Lambdas](#blocks)
3. [String Handling](#strings)
4. [Error Handling](#errors)
5. [Classes & Modules](#classes)
6. [Ruby Idioms](#idioms)
7. [Anti-patterns specific to Ruby](#antipatterns)
---
## 1. Enumerable & Collections {#enumerable}
```ruby
# ❌ Manual accumulation
result = []
items.each do |item|
result << item.name.upcase if item.active?
end
# ✅
result = items.select(&:active?).map { |i| i.name.upcase }
```
```ruby
# ❌ Manual grouping
grouped = {}
items.each do |item|
grouped[item.category] ||= []
grouped[item.category] << item
end
# ✅
grouped = items.group_by(&:category)
```
```ruby
# ❌ Manual sum
total = 0
orders.each { |o| total += o.amount }
# ✅
total = orders.sum(&:amount)
```
```ruby
# ❌ Checking existence then accessing
if hash.key?(key)
value = hash[key]
end
# ✅
value = hash[key] # returns nil if missing
# or with default:
value = hash.fetch(key, default_value)
# or raising on missing:
value = hash.fetch(key) # raises KeyError
```
**Prefer `map`/`select`/`reject`/`sum` over manual loops. Use `&:method` for single-method blocks.**
---
## 2. Blocks, Procs & Lambdas {#blocks}
```ruby
# ❌ Explicit block-to-proc conversion when unnecessary
items.map { |item| item.to_s }
# ✅
items.map(&:to_s)
```
```ruby
# ❌ Proc.new when lambda is safer (arity check + return behavior)
handler = Proc.new { |x| x * 2 }
# ✅
handler = ->(x) { x * 2 }
```
```ruby
# ❌ Multi-line block with { }
items.map { |item|
result = transform(item)
validate(result)
result
}
# ✅ — do/end for multi-line, { } for single-line
items.map do |item|
result = transform(item)
validate(result)
result
end
```
---
## 3. String Handling {#strings}
```ruby
# ❌ String concatenation in loop
result = ""
items.each { |i| result += i.name + ", " }
# ✅
result = items.map(&:name).join(", ")
```
```ruby
# ❌ String concatenation for assembly
greeting = "Hello, " + name + "! You have " + count.to_s + " messages."
# ✅
greeting = "Hello, #{name}! You have #{count} messages."
```
```ruby
# ❌ Mutable string where frozen is fine (Ruby 3+ encourages frozen)
SEPARATOR = ", "
# ✅
SEPARATOR = ", ".freeze
# or add `# frozen_string_literal: true` at file top
```
**Use heredocs (`<<~HEREDOC`) for multi-line strings. `<<~` strips indentation.**
---
## 4. Error Handling {#errors}
```ruby
# ❌ Rescuing Exception (catches EVERYTHING including SignalException, SystemExit)
begin
risky
rescue Exception => e
log(e)
end
# ✅ — rescue StandardError (the default)
begin
risky
rescue StandardError => e
log(e)
raise
end
# or just: rescue => e (same as StandardError)
```
```ruby
# ❌ Using rescue as flow control
begin
value = hash.fetch(key)
rescue KeyError
value = default
end
# ✅
value = hash.fetch(key, default)
```
```ruby
# ❌ Inline rescue hiding errors
result = dangerous_operation rescue nil
# ✅ — inline rescue only for truly trivial fallbacks
result = Integer(input) rescue nil # acceptable for parsing
```
---
## 5. Classes & Modules {#classes}
```ruby
# ❌ Manual accessors
class User
def name
@name
end
def name=(value)
@name = value
end
end
# ✅
class User
attr_accessor :name
end
```
```ruby
# ❌ Deep inheritance for shared behavior
class Animal; end
class Pet < Animal; end
class Dog < Pet; end
# ✅ — mixins for shared behavior, inheritance for "is-a"
module Trainable
def train = puts("Training #{name}")
end
class Dog
include Trainable
attr_reader :name
def initialize(name) = @name = name
end
```
```ruby
# ❌ Class with only class methods (namespace via class)
class MathUtils
def self.square(x) = x * x
def self.cube(x) = x ** 3
end
# ✅
module MathUtils
module_function
def square(x) = x * x
def cube(x) = x ** 3
end
```
---
## 6. Ruby Idioms {#idioms}
```ruby
# ❌ Explicit boolean return
def active?
if status == :active
true
else
false
end
end
# ✅
def active? = status == :active
```
```ruby
# ❌ nil check before method call
if user && user.name
puts user.name
end
# ✅ (Ruby 2.3+)
puts user&.name if user&.name
# or with safe navigation:
user&.name&.then { |n| puts n }
```
```ruby
# ❌ Conditional assignment verbosely
if @cache.nil?
@cache = expensive_compute
end
# ✅
@cache ||= expensive_compute
```
```ruby
# ❌ Multiple assignment from array manually
first = arr[0]
second = arr[1]
# ✅
first, second = arr
```
---
## 7. Anti-patterns specific to Ruby {#antipatterns}
| Anti-pattern | Preferred |
|---|---|
| `rescue Exception` | `rescue StandardError` |
| `for x in collection` | `collection.each` |
| Manual `attr_reader`/`writer` | `attr_accessor` / `attr_reader` |
| `class` for pure namespace | `module` |
| String concatenation with `+` | string interpolation `#{}` |
| `if !condition` | `unless condition` |
| `== true` / `== false` | truthy/falsy check directly |
| `and`/`or` for control flow | `&&`/`||` (different precedence) |
| `return` at end of method | implicit return (last expression) |
| Monkey-patching core classes in production | refinements or wrapper |
| `eval` / `send` for known methods | direct method call |
## Limitations
- These are language-specific guidelines and do not cover overall architectural decisions.
- Over-compression might reduce readability; apply judgement.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!