Use when writing Ruby code, implementing Ruby features, or needing Ruby best practices and idioms.
From psnnpx claudepluginhub aladac/claude-pluginsThis skill uses the workspace's default tool permissions.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Optimizes cloud costs on AWS, Azure, GCP via rightsizing, tagging strategies, reserved instances, spot usage, and spending analysis. Use for expense reduction and governance.
| Tool | Purpose |
|---|---|
Read | Read .rb files |
Write | Create new Ruby files |
Edit | Modify Ruby code |
Bash | Run bundle, ruby, rspec, standardrb, srb |
Glob | Find Ruby files (*.rb) |
Grep | Search Ruby code |
psn:code:ruby-cli - Thor CLI developmentpsn:code:ruby-test - RSpec testingpsn:code:ruby-rails - Rails API developmentpsn:code:ruby-gem - Gem developmentpsn:code:ruby-tooling - Lint/format/typecheckpsn:code:ruby-validate - Full validation workflowModern Ruby idioms focused on readability and maintainability.
# Prefer: Flat declaration
module Foo::Bar::Baz
def self.call
end
end
# Avoid: Nested modules (unless you need to define parent modules)
module Foo
module Bar
module Baz
end
end
end
# Prefer: module_function for utility modules
module StringUtils
module_function
def truncate(str, length)
str.length > length ? "#{str[0, length - 3]}..." : str
end
def slugify(str)
str.downcase.strip.gsub(/\s+/, '-').gsub(/[^\w-]/, '')
end
end
module Api::Client
class << self
def get(url)
# ...
end
private
def connection
@connection ||= Faraday.new
end
end
end
Encapsulate business logic in callable objects:
class CreateOrder
def self.call(...)
new(...).call
end
def initialize(user:, items:, coupon: nil)
@user = user
@items = items
@coupon = coupon
end
def call
return failure(:no_items) if @items.empty?
return failure(:invalid_coupon) unless valid_coupon?
order = build_order
order.save ? success(order) : failure(order.errors)
end
private
# ... helper methods
end
Order = Data.define(:id, :items, :status) do
def total
items.sum(&:price)
end
end
Point = Struct.new(:x, :y, keyword_init: true) do
def distance_from_origin
Math.sqrt(x**2 + y**2)
end
end
case response
in { status: 200, body: }
process(body)
in { status: 404 }
handle_not_found
in { status: 500, error: message }
log_error(message)
end
# Always use keywords for clarity
fetch_data(url, use_cache: false, timeout: 30)
# Ruby 3.0+: Forward all arguments
def wrapper(...)
wrapped_method(...)
end
module MyApp
class Error < StandardError; end
class ValidationError < Error; end
class NotFoundError < Error; end
end
def fetch_user(id)
api.get("/users/#{id}")
rescue Faraday::ResourceNotFound
nil
rescue Faraday::TimeoutError => e
raise MyApp::ApiError.new("Service unavailable", status: 503)
end
# Simple
def current_user
@current_user ||= User.find(session[:user_id])
end
# With Nil/False Values
def feature_enabled?
return @feature_enabled if defined?(@feature_enabled)
@feature_enabled = expensive_check
end
Prefer dry-rb gems where applicable:
| Need | Use |
|---|---|
| Validation | dry-validation / dry-schema |
| Types & structs | dry-types / dry-struct |
| Dependency injection | dry-auto_inject + dry-container |
| Transactions | dry-transaction / dry-monads |
Never commit:
binding.pry or byebugputs / p for debuggingeval with user inputrescue => e)