← Back to list

ruby-core
by bastos
Bastos' Claude Code Ruby Plugin Marketplace
⭐ 0🍴 0📅 Jan 24, 2026
SKILL.md
name: ruby-core description: This skill should be used when the user asks about "Ruby basics", "blocks", "procs", "lambdas", "enumerables", "iterators", "pattern matching", "error handling", "exceptions", "Ruby 3 features", "Ractors", "Data class", "endless methods", "refinements", or needs guidance on Ruby language features and idioms. version: 1.0.0
Ruby Core Language Features
Comprehensive guide to Ruby 3.x core language features, idioms, and best practices.
Blocks, Procs, and Lambdas
Blocks
Blocks are anonymous functions passed to methods:
# Block with do...end (multi-line)
[1, 2, 3].each do |n|
puts n * 2
end
# Block with braces (single-line, returns value)
doubled = [1, 2, 3].map { |n| n * 2 }
# Yielding to blocks
def with_timing
start = Time.now
result = yield
puts "Took #{Time.now - start}s"
result
end
with_timing { expensive_operation }
# Block with arguments
def transform(value)
yield(value) if block_given?
end
transform(5) { |n| n * 2 } # => 10
# Capturing blocks as Proc
def save_block(&block)
@callback = block
end
Procs vs Lambdas
# Proc - flexible argument handling, returns from enclosing method
my_proc = Proc.new { |a, b| a + b }
my_proc = proc { |a, b| a + b }
my_proc.call(1, 2) # => 3
my_proc.call(1, 2, 3) # => 3 (extra args ignored)
my_proc.call(1) # => TypeError (nil + 1)
# Lambda - strict argument checking, returns to caller
my_lambda = ->(a, b) { a + b }
my_lambda = lambda { |a, b| a + b }
my_lambda.call(1, 2) # => 3
my_lambda.call(1, 2, 3) # ArgumentError
my_lambda.call(1) # ArgumentError
# Key difference: return behavior
def proc_return
p = Proc.new { return "from proc" }
p.call
"after proc" # Never reached
end
def lambda_return
l = -> { return "from lambda" }
l.call
"after lambda" # This executes
end
Method Objects
# Convert method to proc
def double(n) = n * 2
[1, 2, 3].map(&method(:double)) # => [2, 4, 6]
# Unbound methods
unbound = String.instance_method(:upcase)
bound = unbound.bind("hello")
bound.call # => "HELLO"
Enumerables
Core Enumerable Methods
numbers = [1, 2, 3, 4, 5]
# Transformation
numbers.map { |n| n * 2 } # => [2, 4, 6, 8, 10]
numbers.flat_map { |n| [n, n * 2] } # => [1, 2, 2, 4, 3, 6, 4, 8, 5, 10]
# Filtering
numbers.select { |n| n.even? } # => [2, 4]
numbers.reject { |n| n.even? } # => [1, 3, 5]
numbers.filter_map { |n| n * 2 if n.even? } # => [4, 8]
# Reduction
numbers.reduce(0) { |sum, n| sum + n } # => 15
numbers.reduce(:+) # => 15
numbers.sum # => 15
# Searching
numbers.find { |n| n > 3 } # => 4
numbers.find_index { |n| n > 3 } # => 3
numbers.any? { |n| n > 3 } # => true
numbers.all? { |n| n > 0 } # => true
numbers.none? { |n| n > 10 } # => true
numbers.one? { |n| n == 3 } # => true
# Grouping
numbers.group_by { |n| n % 2 } # => {1=>[1,3,5], 0=>[2,4]}
numbers.partition { |n| n.even? } # => [[2,4], [1,3,5]]
numbers.tally # Count occurrences
# Ordering
numbers.sort_by { |n| -n } # => [5, 4, 3, 2, 1]
numbers.max_by { |n| n % 3 } # => 2
numbers.min_by { |n| n % 3 } # => 3
# Chaining
numbers.lazy.select { |n| n.even? }.map { |n| n * 2 }.first(2)
Lazy Enumerables
# Process large/infinite sequences efficiently
(1..Float::INFINITY)
.lazy
.select { |n| n % 3 == 0 }
.map { |n| n * 2 }
.first(5)
# => [6, 12, 18, 24, 30]
# Memory-efficient file processing
File.foreach("large_file.txt")
.lazy
.map(&:chomp)
.select { |line| line.include?("ERROR") }
.first(10)
Pattern Matching (Ruby 3.x)
Basic Patterns
case value
in Integer => n if n > 0
"positive integer: #{n}"
in Integer
"non-positive integer"
in String => s
"string: #{s}"
in [first, *rest]
"array starting with #{first}"
in { name:, age: }
"person: #{name}, #{age}"
in nil
"nothing"
else
"unknown"
end
Array Patterns
case [1, 2, 3]
in [a, b, c]
"three elements: #{a}, #{b}, #{c}"
in [head, *tail]
"head: #{head}, tail: #{tail}"
in [*, last]
"last element: #{last}"
in [first, *, last]
"first: #{first}, last: #{last}"
end
Hash Patterns
case { name: "Alice", age: 30, role: "admin" }
in { name: "Alice", role: }
"Alice is #{role}"
in { name:, age: 18.. }
"#{name} is an adult"
in { **rest }
"other: #{rest}"
end
Guard Clauses
case number
in n if n.negative?
"negative"
in n if n.zero?
"zero"
in n if n.positive?
"positive"
end
Pinning
expected = 42
case value
in ^expected
"matched expected value"
in other
"got #{other} instead of #{expected}"
end
Error Handling
Exception Basics
begin
risky_operation
rescue SpecificError => e
handle_specific_error(e)
rescue StandardError => e
handle_general_error(e)
else
# Runs if no exception
success_callback
ensure
# Always runs
cleanup
end
# Inline rescue (use sparingly)
value = risky_operation rescue default_value
# Retry pattern
attempts = 0
begin
attempts += 1
unreliable_api_call
rescue NetworkError
retry if attempts < 3
raise
end
Custom Exceptions
class ApplicationError < StandardError; end
class ValidationError < ApplicationError
attr_reader :field, :value
def initialize(message, field:, value:)
@field = field
@value = value
super(message)
end
end
raise ValidationError.new("Invalid email", field: :email, value: input)
Exception Hierarchy
Exception
├── NoMemoryError
├── ScriptError
├── SignalException
├── SystemExit
└── StandardError (catch this, not Exception)
├── ArgumentError
├── IOError
├── NameError
│ └── NoMethodError
├── RangeError
├── RuntimeError (default for `raise`)
├── TypeError
└── ZeroDivisionError
Ruby 3.x Features
Data Classes (Ruby 3.2+)
# Immutable value objects
Point = Data.define(:x, :y)
p = Point.new(1, 2)
p.x # => 1
p.with(x: 10) # => Point(x: 10, y: 2)
# With methods
Point = Data.define(:x, :y) do
def distance_from_origin
Math.sqrt(x**2 + y**2)
end
end
Ractors (Parallel Execution)
# True parallelism without GVL
ractors = 4.times.map do |i|
Ractor.new(i) do |n|
# Runs in parallel
heavy_computation(n)
end
end
results = ractors.map(&:take)
Endless Methods
# Single-expression method shorthand
def double(n) = n * 2
def greet(name) = "Hello, #{name}!"
def square(n) = n ** 2
Refinements
module StringExtensions
refine String do
def shout
upcase + "!"
end
end
end
class Greeter
using StringExtensions
def greet(name)
"hello #{name}".shout # => "HELLO NAME!"
end
end
# Outside the class, shout is not available
"test".shout # NoMethodError
Numbered Block Parameters
# Use _1, _2, etc. for simple blocks
[1, 2, 3].map { _1 * 2 } # => [2, 4, 6]
[[1, 2], [3, 4]].map { _1 + _2 } # => [3, 7]
Best Practices
Guard Clauses
# Prefer
def process(value)
return if value.nil?
return "empty" if value.empty?
# main logic
end
# Over
def process(value)
if value
if value.empty?
"empty"
else
# main logic
end
end
end
Safe Navigation
# Safe navigation operator
user&.profile&.avatar&.url
# With default
user&.profile&.avatar&.url || "default.png"
Frozen String Literals
# frozen_string_literal: true
# All string literals are frozen, improving performance
name = "Alice" # Frozen, cannot be mutated
name << " Bob" # FrozenError
# Use +@ to get mutable copy
mutable = +name
mutable << " Bob" # OK
Score
Total Score
65/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
✓LICENSE
ライセンスが設定されている
+10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
✓最近の活動
1ヶ月以内に更新
+10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
✓タグ
1つ以上のタグが設定されている
+5
Reviews
💬
Reviews coming soon
