Install
$ agentstack add skill-zarpay-rails-template-ruby ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Ruby Language Skill
Overview
Opinionated Ruby conventions and idioms for writing idiomatic Ruby 3.x+ code. Focuses on patterns agents miss by default — the Weirich raise/fail distinction, safe nil-aware memoization, result objects over exceptions for expected failures, and performance-conscious enumeration.
Error Handling Conventions
Weirich raise/fail Convention
Use fail for first-time exceptions, raise only for re-raising:
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
Custom Exception Hierarchies
Group domain exceptions under a base error:
module MyApp
class Error e
fallback ? fallback.call(e) : raise
end
user = fetch_user(999) { |_| User.new(name: "Guest") }
See references/error_handling.md for full patterns and retry strategies.
Modern Ruby (3.x+)
Pattern Matching
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
Other 3.x+ Features
# 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}
See references/modern_ruby.md for ractors, fiber scheduler, RBS types, and advanced pattern matching.
Performance Quick Wins
Frozen String Literals
# frozen_string_literal: true
# Add to top of every file. Prevents mutation, reduces allocations.
# When you need mutable: String.new("hello") or +"hello"
Efficient Enumeration
# 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)
Memoization with nil/false Caveat
# 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
String Building
# 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
See references/performance.md for YJIT, GC tuning, benchmarking, and profiling tools.
Ruby Idioms to Prefer
Guard Clauses
def process(value)
return unless value
return unless value.valid?
# main logic here
end
Literal Array Constructors
STATES = %w[draft published archived] # word array
FIELDS = %i[name email created_at] # symbol array
Hash#fetch for Required Keys
config.fetch(:api_key) # raises KeyError if missing
config.fetch(:timeout, 30) # default value
config.fetch(:handler) { build_handler } # lazy default
Safe Navigation
user&.profile&.avatar_url # returns nil if any link is nil
Predicate and Bang Conventions
?suffix: returns boolean (empty?,valid?,admin?)!suffix: dangerous version - mutates receiver or raises on failure (save!,sort!)- Always provide a non-bang alternative when defining bang methods
Common Mistakes
| Mistake | Fix | |---------|-----| | raise for new exceptions | Use fail; reserve raise for re-raising (Weirich convention) | | @var \|\|= compute when result can be nil/false | Use defined?(@var) check instead | | String concatenation with += in loops | Use << or .join — += is O(n²) | | rescue Exception | Rescue StandardError — Exception catches SignalException, NoMemoryError | | Deep &. chains (3+ links) | Extract to a method or use explicit nil check | | Missing # frozen_string_literal: true | Add to top of every file |
References
references/modern_ruby.md- Pattern matching, ractors, fiber scheduler, RBS typesreferences/error_handling.md- Exception hierarchies, result objects, retry patternsreferences/performance.md- YJIT, GC tuning, benchmarking, profilingreferences/ood-philosophy.md- OOD principles, naming, SOLID, TRUE heuristic, Law of Demeter
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: zarpay
- Source: zarpay/rails-template
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.