Ruby チートシート

基本操作

Rubyの基本的な構文やデータ型に関する操作です。

変数と定数

種類命名規則説明コード例
ローカル変数小文字 or `_` で始まるメソッド内やブロック内など、定義されたスコープでのみ有効。
message = "こんにちは"
_internal_val = 10
インスタンス変数`@` で始まるオブジェクトごとに存在する変数。クラスのメソッド内で使用。
class User def initialize(name) @name = name end
end
クラス変数`@@` で始まるクラスとそのサブクラス、インスタンス間で共有される変数。
class Counter @@count = 0 def initialize @@count += 1 end def self.count @@count end
end
グローバル変数`$` で始まるプログラム全体からアクセス可能。使用は推奨されないことが多い。
$program_status = "running"
定数大文字で始まる一度代入すると再代入時に警告が出る。クラス名やモジュール名も定数。
PI = 3.14159
AppName = "MyApp"

主なデータ型

説明リテラル例
整数 (Integer)整数を表す。FixnumとBignumが内部的に使われる(Ruby 2.4以降はIntegerに統合)。100, -5, 1_000_000
浮動小数点数 (Float)実数を表す。3.14, -0.5, 1.0e-5
文字列 (String)文字の並び。シングルクォートとダブルクォートで挙動が異なる。'hello', "world\n", %q{Ruby}, %Q| #{Time.now} |
配列 (Array)順序付けられたオブジェクトの集まり。異なる型の要素を混在可能。[1, "two", 3.0], %w[a b c], %i[x y z]
ハッシュ (Hash)キーと値のペアの集まり。順序はRuby 1.9以降保持される。{'key1' => 'value1', :key2 => 2}, {key1: 'value1', key2: 2}
シンボル (Symbol)文字列に似ているが、内部的には整数で管理される。効率的な識別子。:success, :error_code, :"a symbol"
真偽値 (TrueClass/FalseClass)真 (true) または偽 (false) を表す。true, false
nil (NilClass)何もないことを表す特別な値。nil
範囲 (Range)開始値から終了値までの範囲を表す。1..10 (10を含む), 1...10 (10を含まない)

演算子

算術演算子 (+, -, *, /, %, **), 比較演算子 (==, !=, >, <, >=, <=, <=>), 論理演算子 (&&, ||, !, and, or, not), 代入演算子 (=, +=, -=, etc.), 三項演算子 (条件 ? 真の場合 : 偽の場合) などがあります。

# 算術
a = 10 + 5 # a は 15
b = 10 * 2 # b は 20
c = 10 / 3 # c は 3 (整数除算)
d = 10.0 / 3 # d は 3.333...
e = 10 % 3 # e は 1 (剰余)
f = 2 ** 3 # f は 8 (べき乗)
# 比較
puts 5 == 5 # true
puts 5 != 4 # true
puts 5 < 10 # true
puts 5 <=> 10 # -1 (左が小さい)
puts 10 <=> 5 # 1 (左が大きい)
puts 5 <=> 5 # 0 (等しい)
# 論理
age = 25
is_student = false
puts age >= 20 && !is_student # true
# 代入
count = 0
count += 1 # count = count + 1 と同じ
# 三項演算子
status = age >= 18 ? "adult" : "minor"
puts status # "adult"

コメント

# から行末までがコメントになります。複数行コメントは =begin=end で囲みますが、あまり使われません。

# これは一行コメントです
puts "Hello" # ここもコメント
=begin
これは
複数行の
コメントです
=end

制御構造

プログラムの流れを制御するための構文です。

条件分岐

if / elsif / else / end

score = 75
if score >= 80 puts "優"
elsif score >= 60 puts "良"
else puts "可"
end
# 後置if (修飾子)
puts "合格" if score >= 60

unless / else / end

if not と同様ですが、条件が偽のときに実行されます。

is_logged_in = false
unless is_logged_in puts "ログインしてください"
end
# 後置unless (修飾子)
puts "処理を実行します" unless is_logged_in == true

case / when / else / end

signal = "red"
case signal
when "red" puts "止まれ"
when "yellow" puts "注意"
when "green", "blue" # 複数の値を指定可能 puts "進め"
else puts "不明な信号"
end
# オブジェクトや範囲も使用可能
age = 15
case age
when 0..5 puts "幼児"
when 6..12 puts "小学生"
else puts "中学生以上"
end
# === 演算子が使われる
value = "text"
case value
when String puts "文字列です"
when Integer puts "整数です"
end

繰り返し

while / end

条件が真の間、繰り返し実行します。

count = 0
while count < 3 puts "カウント: #{count}" count += 1
end
# 後置while (修飾子)
balance = 1000
balance *= 1.05 while balance < 1500

until / end

条件が偽の間、繰り返し実行します (while not と同様)。

counter = 5
until counter == 0 puts counter counter -= 1
end
# 後置until (修飾子)
sleep(1) until File.exist?("result.txt")

for / in / end

コレクション (配列や範囲など) の要素を反復処理します。内部的には each が呼ばれます。

numbers = [1, 2, 3]
for num in numbers puts num * 2
end
for i in 0..2 puts "Index: #{i}"
end

each (イテレータ)

コレクションの各要素に対してブロックを実行します。最もRubyらしい繰り返し方法です。

fruits = ["apple", "banana", "cherry"]
fruits.each do |fruit| puts "I like #{fruit}."
end
# ブロックを {} で書くことも可能 (通常1行の場合)
(1..3).each { |n| puts n }
# インデックス付き
fruits.each_with_index do |fruit, index| puts "#{index}: #{fruit}"
end

times

指定した回数だけブロックを実行します。

5.times do |i| puts "#{i+1}回目の繰り返し"
end
3.times { puts "Hello!" }

loop / do / end

無限ループを作成します。break で脱出する必要があります。

count = 0
loop do puts "Looping..." count += 1 break if count >= 3 # 脱出条件
end

繰り返し制御

キーワード説明コード例
break最も内側のループを中断し、ループの次の処理へ移る。
[1, 2, 3, 4, 5].each do |n| break if n == 3 puts n # 1, 2 が出力される
end
puts "ループ終了"
next現在の繰り返し処理をスキップし、次の繰り返しへ移る。
[1, 2, 3, 4, 5].each do |n| next if n.even? # 偶数はスキップ puts n # 1, 3, 5 が出力される
end
redo現在の繰り返し処理を、条件評価などをやり直さずに最初からもう一度実行する。
attempts = 0
data = [1, 2, 'stop', 3]
data.each do |item| begin puts "Processing: #{item}" raise "Error on stop" if item == 'stop' && attempts == 0 attempts = 0 # 成功したらリセット rescue attempts += 1 puts "Retry attempt: #{attempts}" redo # 同じ item で再試行 end
end

メソッド

処理をまとめたものです。関数とも呼ばれます。

メソッド定義と呼び出し

# メソッド定義
def greet(name) puts "Hello, #{name}!"
end
# メソッド呼び出し
greet("Alice") # "Hello, Alice!" と出力
greet "Bob" # 括弧は省略可能 (引数がある場合)
# 引数なしメソッド
def say_goodbye puts "Goodbye!"
end
say_goodbye # 括弧なしで呼び出し

引数

デフォルト引数

def welcome(user = "Guest") puts "Welcome, #{user}!"
end
welcome # "Welcome, Guest!"
welcome("Admin") # "Welcome, Admin!"

可変長引数

def print_args(*args) puts "引数の数: #{args.length}" args.each { |arg| puts "- #{arg}" }
end
print_args(1, "two", :three)

キーワード引数

# デフォルト値付きキーワード引数
def create_user(name:, email:, admin: false) puts "Name: #{name}, Email: #{email}, Admin: #{admin}"
end
create_user(name: "Eve", email: "eve@example.com")
create_user(name: "Frank", email: "frank@example.com", admin: true)
# 順番は関係ない
# デフォルト値なしキーワード引数 (呼び出し時に必須)
def configure(host:, port:) puts "Connecting to #{host}:#{port}"
end
configure(host: "localhost", port: 8080)
# 可変長キーワード引数
def print_options(id, **options) puts "ID: #{id}" options.each { |key, value| puts "#{key}: #{value}" }
end
print_options(101, color: "red", size: "large")
通常の引数、デフォルト引数、可変長引数、キーワード引数、可変長キーワード引数を組み合わせる際の順序に注意が必要です (通常 -> デフォルト -> 可変長 -> キーワード(デフォルトなし) -> キーワード(デフォルトあり) -> 可変長キーワード)。

戻り値

メソッド内で最後に評価された式の結果が暗黙的に戻り値となります。return キーワードで明示的に値を返すこともできます。

def add(a, b) a + b # この結果が戻り値
end
result = add(3, 4) # result は 7
def check_status(code) if code == 0 return "Success" # 明示的に返す end # codeが0でない場合、ここが評価される (nilが返る) "Error or Unknown" # これを書けば nil ではなくこの文字列が返る
end
status1 = check_status(0) # status1 は "Success"
status2 = check_status(1) # status2 は "Error or Unknown"

ブロック付きメソッド (yield)

メソッド呼び出し時にコードブロック (do..end または {..}) を渡し、メソッド内でそのブロックを実行できます。

def process_data puts "処理開始" result = yield # ブロックを実行し、その結果を受け取る puts "ブロックの結果: #{result}" puts "処理終了"
end
process_data do # このブロックが yield で実行される data = [1, 2, 3] data.sum # このブロックの戻り値
end
# 出力:
# 処理開始
# ブロックの結果: 6
# 処理終了
# ブロックに引数を渡す
def repeat(n) n.times do |i| yield i # ブロックに現在のカウントを渡す end
end
repeat(3) do |count| puts "繰り返し #{count + 1} 回目"
end
# ブロックが渡されたか確認
def maybe_yield if block_given? yield else puts "ブロックが渡されませんでした" end
end
maybe_yield { puts "ブロック実行!" }
maybe_yield

クラスとモジュール

オブジェクト指向プログラミングの基本的な構成要素です。

クラス定義とインスタンス化

# クラス定義
class Dog # 初期化メソッド (コンストラクタ) def initialize(name, breed) @name = name # インスタンス変数 @breed = breed end # インスタンスメソッド def bark puts "#{@name} says Woof!" end # クラスメソッド (self.メソッド名) def self.info puts "This is a Dog class." end # アクセサメソッドの定義 (後述) attr_reader :name, :breed attr_writer :name # name を変更可能にする # attr_accessor :name # 読み書き両方可能にする場合
end
# インスタンス化 (オブジェクト生成)
my_dog = Dog.new("Pochi", "Shiba Inu")
# インスタンスメソッドの呼び出し
my_dog.bark # "Pochi says Woof!"
# クラスメソッドの呼び出し
Dog.info # "This is a Dog class."
# アクセサ経由でのアクセス
puts my_dog.name # "Pochi"
my_dog.name = "Taro" # attr_writer があるので可能
puts my_dog.name # "Taro"
# puts my_dog.breed = "Akita" # エラー (attr_writer :breed がない)

インスタンス変数とクラス変数

  • インスタンス変数 (@variable): 各オブジェクトが個別に持つデータ。initialize メソッドで初期化されることが多い。
  • クラス変数 (@@variable): クラスとその全てのインスタンス、サブクラスで共有されるデータ。
class Car @@total_cars = 0 # クラス変数 def initialize(make) @make = make # インスタンス変数 @@total_cars += 1 end def display_make puts "This car is a #{@make}" end def self.total_cars @@total_cars end
end
car1 = Car.new("Toyota")
car2 = Car.new("Honda")
car1.display_make # "This car is a Toyota"
car2.display_make # "This car is a Honda"
puts Car.total_cars # 2
クラス変数は継承関係で意図しない挙動を示すことがあるため、注意深く使用するか、代替手段(クラスインスタンス変数など)を検討することがあります。

アクセサメソッド

インスタンス変数へのアクセス(読み取り・書き込み)を提供するメソッド。

  • attr_reader :var1, :var2 : 読み取りメソッド (var1, var2) を自動生成。
  • attr_writer :var1, :var2 : 書き込みメソッド (var1=, var2=) を自動生成。
  • attr_accessor :var1, :var2 : 読み取り・書き込み両方のメソッドを自動生成。
class Book attr_accessor :title # 読み書き可能 attr_reader :author # 読み取り専用 attr_writer :isbn # 書き込み専用 (あまり使わない) def initialize(title, author) @title = title @author = author end def set_isbn(code) # attr_writer :isbn があれば self.isbn = code と書ける @isbn = code # 直接代入も可能 end def get_isbn @isbn # 直接アクセスは可能だが、アクセサ経由が一般的 end
end
book = Book.new("Ruby Guide", "Yukihiro Matsumoto")
puts book.title # "Ruby Guide"
book.title = "Revised Ruby Guide"
puts book.title # "Revised Ruby Guide"
puts book.author # "Yukihiro Matsumoto"
# book.author = "Matz" # エラー (attr_writerがない)
book.set_isbn("978-4-...")
puts book.get_isbn

継承

既存のクラス (スーパークラス) の機能を引き継いだ新しいクラス (サブクラス) を作成します。

class Animal def initialize(name) @name = name end def speak puts "#{@name} makes a sound." end
end
# Animalクラスを継承したDogクラス
class Dog < Animal # speakメソッドをオーバーライド(上書き) def speak puts "#{@name} barks!" end def fetch puts "#{@name} fetches the ball." end
end
# Animalクラスを継承したCatクラス
class Cat < Animal def speak # スーパークラスの同名メソッドを呼び出す super puts "(Specifically, meows)" end
end
dog = Dog.new("Buddy")
dog.speak # "Buddy barks!"
dog.fetch # "Buddy fetches the ball."
cat = Cat.new("Whiskers")
cat.speak
# "Whiskers makes a sound."
# "(Specifically, meows)"

モジュールとMix-in

モジュールはメソッドや定数の集まりです。クラスにincludeprependすることで、モジュールの機能を追加 (Mix-in) できます。extendはクラスメソッドとして追加します。

module Loggable def log(message) puts "[LOG] #{Time.now}: #{message}" end
end
module Flyable def fly puts "I'm flying!" end
end
class Product include Loggable # インスタンスメソッドとしてlogを追加 def initialize(name) @name = name end def save log("Saving #{@name}...") # 保存処理... log("#{@name} saved.") end
end
class Bird extend Flyable # クラスメソッドとしてflyを追加 (特異メソッド) def self.description "Birds can often fly." end
end
class Airplane include Flyable # インスタンスメソッドとしてflyを追加 def take_off puts "Taking off..." fly # include されたメソッドを呼び出す end
end
product = Product.new("Book")
product.save # Loggableのlogメソッドが使える
# extend はクラス自体にメソッドを追加する
# Bird.fly # "I'm flying!"
# include はインスタンスにメソッドを追加する
plane = Airplane.new
plane.take_off
# 名前空間としてのモジュール
module NetworkUtils class Connection def connect puts "Connecting..." end end def self.ping(host) puts "Pinging #{host}..." end
end
conn = NetworkUtils::Connection.new
conn.connect
NetworkUtils.ping("google.com")
Mix-in方法挙動メソッド探索順序 (例: Class A include M)
include MモジュールMのメソッドをインスタンスメソッドとして追加。継承チェーンにおいて、クラスの直後(スーパークラスの前)にモジュールが挿入される。A -> M -> スーパークラス -> …
prepend MモジュールMのメソッドをインスタンスメソッドとして追加。継承チェーンにおいて、クラスの直前にモジュールが挿入される。同名メソッドがあればモジュールのものが優先される。M -> A -> スーパークラス -> …
extend MモジュールMのメソッドをクラスメソッド(特異メソッド)として追加。クラスオブジェクト自体に追加される。(クラスオブジェクトの特異クラス) -> M -> …

文字列操作

文字列 (String) に関する様々な操作です。

目的メソッド例コード例
生成・結合+, <<, concat, 式展開#{}
s1 = "Hello"
s2 = " World"
puts s1 + s2 # "Hello World" (新しい文字列)
puts s1 << s2 # "Hello World" (s1自体を変更)
s1.concat("!") # "Hello World!" (s1自体を変更)
name = "Ruby"
puts "Lang: #{name}" # "Lang: Ruby"
繰り返し*
puts "Go! " * 3 # "Go! Go! Go! "
長さ・空か判定length, size, empty?
str = "abc"
puts str.length # 3
puts "".empty? # true
文字・部分文字列アクセス[], slice
str = "abcdef"
puts str[0] # "a"
puts str[1..3] # "bcd"
puts str[-1] # "f"
puts str.slice(2, 3) # "cde"
置換sub, gsub, sub!, gsub!
text = "apple orange apple"
puts text.sub("apple", "banana") # "banana orange apple" (最初のみ)
puts text.gsub("apple", "banana") # "banana orange banana" (全て)
# `!` 付きは自身を変更
検索include?, index, rindex, start_with?, end_with?, match, scan
str = "Ruby Programming"
puts str.include?("Pro") # true
puts str.index("gram") # 8
puts str.start_with?("Ruby") # true
puts str.match?(/Pro(gram)+/) # true
puts str.scan(/\w+/) # ["Ruby", "Programming"]
分割・結合split, join (配列メソッド)
csv = "a,b,c"
parts = csv.split(',') # ["a", "b", "c"]
puts parts.join('-') # "a-b-c"
大文字/小文字変換upcase, downcase, capitalize, swapcase
str = "hELLo WoRLd"
puts str.upcase # "HELLO WORLD"
puts str.downcase # "hello world"
puts str.capitalize # "Hello world"
puts str.swapcase # "Hello wOrlD"
空白除去strip, lstrip, rstrip
str = " text "
puts str.strip # "text" (両端)
puts str.lstrip # "text " (左端)
puts str.rstrip # " text" (右端)
文字コード変換encode
# UTF-8 から EUC-JP へ
# utf8_str = "こんにちは"
# euc_str = utf8_str.encode("EUC-JP")
ヒアドキュメント<<IDENTIFIER, <<-IDENTIFIER, <<~IDENTIFIER
query = <<SQL
SELECT *
FROM users
WHERE age > 20;
SQL
# <<- は終端識別子前のインデントを無視
message = <<-MSG This is a message. Indentation is kept. MSG
# <<~ は先頭のインデントと終端識別子前のインデントを無視
code = <<~CODE def example puts "Indented code" end CODE
# code は "def example\n puts \"Indented code\"\nend" になる

配列 (Array) に関する様々な操作です。

目的メソッド例コード例
生成[], Array.new, %w, %i
arr1 = [1, 2, 3]
arr2 = Array.new(3, "a") # ["a", "a", "a"]
arr3 = %w[red green blue] # ["red", "green", "blue"] (文字列の配列)
arr4 = %i[x y z] # [:x, :y, :z] (シンボルの配列)
要素アクセス・代入[], []=, at, first, last, fetch
arr = [:a, :b, :c, :d]
puts arr[0] # :a
puts arr[-1] # :d
puts arr[1..2] # [:b, :c]
arr[1] = :B # arr は [:a, :B, :c, :d]
puts arr.first # :a
puts arr.last # :d
puts arr.fetch(1) # :B
# puts arr.fetch(10) # エラー (IndexError)
puts arr.fetch(10, "default") # "default" (デフォルト値指定)
要素の追加push (<<), unshift, insert
arr = [1, 2]
arr.push(3) # [1, 2, 3] (末尾に追加)
arr << 4 # [1, 2, 3, 4] (同上)
arr.unshift(0) # [0, 1, 2, 3, 4] (先頭に追加)
arr.insert(2, 1.5) # [0, 1, 1.5, 2, 3, 4] (指定位置に追加)
要素の削除pop, shift, delete, delete_at, compact, uniq
arr = [0, 1, nil, 2, 1, nil]
puts arr.pop # nil (末尾を削除して返す) arr は [0, 1, nil, 2, 1]
puts arr.shift # 0 (先頭を削除して返す) arr は [1, nil, 2, 1]
arr.delete(1) # arr は [nil, 2] (指定した値を全て削除)
arr.delete_at(0) # arr は [2] (指定インデックスを削除)
arr = [1, nil, 2, nil]
arr.compact! # arr は [1, 2] (nil要素を削除, `!`は自身を変更)
arr = [1, 2, 2, 3, 1]
arr.uniq! # arr は [1, 2, 3] (重複要素を削除, `!`は自身を変更)
繰り返し・走査each, reverse_each, each_with_index, cycle
nums = [10, 20, 30]
nums.each { |n| puts n }
nums.reverse_each { |n| puts n } # 30, 20, 10
nums.each_with_index { |n, i| puts "#{i}: #{n}" }
# nums.cycle(2) { |n| puts n } # 10, 20, 30, 10, 20, 30
変換・選択 (イテレータ)map (collect), select (filter), reject, find (detect), grep
nums = [1, 2, 3, 4, 5]
squares = nums.map { |n| n * n } # [1, 4, 9, 16, 25]
evens = nums.select { |n| n.even? } # [2, 4]
odds = nums.reject { |n| n.even? } # [1, 3, 5]
first_even = nums.find { |n| n.even? } # 2
words = ["apple", "banana", "apricot"]
a_words = words.grep(/^a/) # ["apple", "apricot"] (正規表現にマッチ)
畳み込み (イテレータ)inject (reduce)
nums = [1, 2, 3, 4]
sum = nums.inject(0) { |result, n| result + n } # 10 (初期値0)
product = nums.inject(1) { |result, n| result * n } # 24 (初期値1)
# シンボルで演算子を指定も可能
sum_short = nums.inject(:+) # 10
product_short = nums.inject(:*) # 24
結合+, concat, | (和集合), & (積集合), - (差集合)
a1 = [1, 2]
a2 = [2, 3]
puts (a1 + a2).inspect # [1, 2, 2, 3] (単純結合)
a1.concat(a2) # a1 は [1, 2, 2, 3] (破壊的)
a1 = [1, 2]; a2 = [2, 3]
puts (a1 | a2).inspect # [1, 2, 3] (和集合、重複削除)
puts (a1 & a2).inspect # [2] (積集合)
puts ([1, 2, 3] - [2, 4]).inspect # [1, 3] (差集合)
ソートsort, sort!, sort_by, sort_by!, reverse, reverse!
arr = [3, 1, 4, 1, 5, 9]
puts arr.sort.inspect # [1, 1, 3, 4, 5, 9]
arr.sort! # 自身をソート
words = ["banana", "apple", "cherry"]
puts words.sort_by { |w| w.length }.inspect # ["apple", "banana", "cherry"] (長さ順)
puts arr.reverse.inspect # 元の配列の逆順 (ソートではない)
検索・判定include?, index, find_index, any?, all?, none?, one?
arr = ["a", "b", "c"]
puts arr.include?("b") # true
puts arr.index("c") # 2
nums = [1, 2, 3, 4]
puts nums.any? { |n| n > 3 } # true (一つでも条件を満たすか)
puts nums.all? { |n| n > 0 } # true (全て条件を満たすか)
puts nums.none? { |n| n < 0 } # true (一つも条件を満たさないか)
その他flatten, join, zip, transpose, sample
nested = [1, [2, 3], [4, [5]]]
puts nested.flatten.inspect # [1, 2, 3, 4, 5] (一次元化)
chars = ["R", "u", "b", "y"]
puts chars.join # "Ruby" (文字列に結合)
a = [1, 2]; b = [3, 4]
puts a.zip(b).inspect # [[1, 3], [2, 4]] (対応する要素でペア配列作成)
matrix = [[1, 2], [3, 4], [5, 6]]
puts matrix.transpose.inspect # [[1, 3, 5], [2, 4, 6]] (行列転置)
puts [1,2,3,4,5].sample # ランダムに1要素取得
puts [1,2,3,4,5].sample(2).inspect # ランダムに2要素取得

ハッシュ操作

ハッシュ (Hash) に関する様々な操作です。

目的メソッド例コード例
生成{}, Hash.new
h1 = { "key1" => "value1", :key2 => 2 }
h2 = { key1: "value1", key2: 2 } # Ruby 1.9以降のシンボルキー記法
h3 = Hash.new("default") # 存在しないキーアクセス時のデフォルト値
要素アクセス・代入[], []=, fetch, values_at
h = { name: "Alice", age: 30 }
puts h[:name] # "Alice"
h[:city] = "Tokyo" # ハッシュに新しいキーと値を追加
puts h.fetch(:age) # 30
# puts h.fetch(:country) # エラー (KeyError)
puts h.fetch(:country, "Unknown") # "Unknown"
puts h.values_at(:name, :city).inspect # ["Alice", "Tokyo"]
キー/値の取得keys, values, to_a
h = { a: 1, b: 2 }
puts h.keys.inspect # [:a, :b]
puts h.values.inspect # [1, 2]
puts h.to_a.inspect # [[:a, 1], [:b, 2]] (キーと値のペアの配列)
削除delete, delete_if, keep_if
h = { a: 10, b: 20, c: 30 }
h.delete(:b) # h は { a: 10, c: 30 }
h.delete_if { |key, value| value < 15 } # h は { c: 30 }
h = { a: 10, b: 20, c: 30 }
h.keep_if { |key, value| value > 15 } # h は { b: 20, c: 30 }
繰り返し・走査each, each_pair, each_key, each_value
h = { name: "Bob", age: 25 }
h.each do |key, value| puts "#{key} is #{value}"
end
h.each_key { |key| puts "Key: #{key}" }
h.each_value { |value| puts "Value: #{value}" }
変換・選択 (イテレータ)map, select (filter), reject, transform_keys, transform_values
h = { a: 1, b: 2, c: 3 }
arr = h.map { |k, v| "#{k}-#{v}" } # ["a-1", "b-2", "c-3"]
selected = h.select { |k, v| v > 1 } # { b: 2, c: 3 }
rejected = h.reject { |k, v| k == :a } # { b: 2, c: 3 }
up_keys = h.transform_keys { |k| k.to_s.upcase } # { "A"=>1, "B"=>2, "C"=>3 }
val_sq = h.transform_values { |v| v * v } # { a: 1, b: 4, c: 9 }
結合・マージmerge, merge! (update)
h1 = { a: 1, b: 2 }
h2 = { b: 3, c: 4 }
merged = h1.merge(h2) # { a: 1, b: 3, c: 4 } (h2の値が優先)
# ブロックで衝突時の処理を定義可能
merged_block = h1.merge(h2) { |key, old_val, new_val| old_val + new_val }
# merged_block は { a: 1, b: 5, c: 4 }
h1.merge!(h2) # h1 が { a: 1, b: 3, c: 4 } になる (破壊的)
検索・判定key? (has_key?, member?), value? (has_value?), empty?, size (length)
h = { x: 100, y: 200 }
puts h.key?(:x) # true
puts h.value?(300) # false
puts {}.empty? # true
puts h.size # 2
その他invert, dig
h = { a: 1, b: 2 }
puts h.invert.inspect # { 1=>:a, 2=>:b } (キーと値を反転)
data = { user: { address: { city: "Kyoto" } } }
puts data.dig(:user, :address, :city) # "Kyoto"
puts data.dig(:user, :name) # nil (途中でキーがなくてもエラーにならない)

正規表現

文字列のパターンマッチングに使用します。

基本

要素説明
リテラル/.../ または %r{...}/ruby/i, %r{^start}
マッチング演算子=~ (マッチ位置 or nil), !~ (マッチしないか)"Hello Ruby" =~ /Ruby/ # => 6
メソッドmatch, match?, scan, [], String#gsub, String#split など"abc".match?(/b/) # true
"12 34 56".scan(/\d+/) # ["12", "34", "56"]

メタ文字と量指定子

記号意味記号意味
.任意の一文字(改行除く) *直前の要素の0回以上の繰り返し
^行の先頭 +直前の要素の1回以上の繰り返し
$行の末尾 ?直前の要素の0回または1回の繰り返し
[...]角括弧内の任意の1文字 {n}直前の要素のn回の繰り返し
[^...]角括弧内を除く任意の1文字 {n,}直前の要素のn回以上の繰り返し
|左右いずれかのパターン (OR) {n,m}直前の要素のn回以上m回以下の繰り返し
(...)グループ化、キャプチャ *?, +?, ??, {n,m}?最短一致(欲張らない)量指定子
\d数字 [0-9] \w英数字とアンダースコア [a-zA-Z0-9_]
\s空白文字 (スペース, タブ, 改行など)\D, \W, \Sそれぞれ \d, \w, \s の否定
\A文字列の先頭 \Z文字列の末尾(改行直前でも可)
\z文字列の完全な末尾 \b単語境界

オプション

オプション意味
i大文字小文字を区別しない"Ruby" =~ /ruby/i # マッチする
mマルチラインモード (.が改行にもマッチする)"a\nb" =~ /^a.b$/m # マッチする
x拡張モード (パターン内の空白と#コメントを無視する)pattern = / \d+ # 1つ以上の数字 \s+ # 1つ以上の空白 \w+ # 1つ以上の単語文字 /x "123 abc" =~ pattern # マッチする

キャプチャと後方参照

str = "Name: Alice, Age: 30"
match_data = str.match(/Name: (\w+), Age: (\d+)/)
if match_data puts "全体: #{match_data[0]}" # Name: Alice, Age: 30 puts "名前: #{match_data[1]}" # Alice (最初のキャプチャ) puts "年齢: #{match_data[2]}" # 30 (2番目のキャプチャ) # 名前付きキャプチャ (?<name>...) md = str.match(/Name: (?<name>\w+), Age: (?<age>\d+)/) puts "名前(名前付き): #{md[:name]}" # Alice puts "年齢(名前付き): #{md[:age]}" # 30
end
# gsub での後方参照
puts "abc".gsub(/(.)/, '\\1\\1') # "aabbcc" (\1 は最初のキャプチャ)
puts "abc".gsub(/(.)/) { $1 * 2 } # "aabbcc" (ブロック内では $1, $2...)

ファイル操作

ファイルやディレクトリの読み書き、操作を行います。

ファイル読み込み

ブロック形式 (推奨)

ファイルが自動的にクローズされます。

# 全体を一度に読み込む
begin content = File.read("my_file.txt") puts content
rescue Errno::ENOENT puts "ファイルが見つかりません。"
end
# 一行ずつ読み込む
begin File.foreach("my_file.txt") do |line| puts "Line: #{line.chomp}" # chompで末尾の改行を削除 end
rescue Errno::ENOENT puts "ファイルが見つかりません。"
end
# File.open を使ったブロック形式
begin File.open("my_file.txt", "r") do |file| # "r"は読み込みモード(デフォルト) file.each_line do |line| # 各行に対する処理 end end
rescue Errno::ENOENT puts "ファイルが見つかりません。"
end

手動クローズ

ensure で確実にクローズする必要があります。

file = nil
begin file = File.open("my_file.txt", "r") # ファイル操作... content = file.read puts content
rescue Errno::ENOENT puts "ファイルが見つかりません。"
ensure file&.close # fileがnilでない場合のみcloseを呼ぶ
end

ファイル書き込み

モード説明コード例 (ブロック形式)
w書き込みモード。ファイルが存在すれば上書き、なければ新規作成。
File.open("output.txt", "w") do |file| file.puts "これは最初の行です。" file.write "これは2行目です。(改行なし)" file.print "これも2行目。\n" # printは改行しない
end
a追記モード。ファイルが存在すれば末尾に追加、なければ新規作成。
File.open("output.txt", "a") do |file| file.puts "これは追記された行です。"
end
r+読み書きモード。ファイルの先頭から開始。ファイルが存在する必要あり。
# 注意: 使い方によっては複雑になる
File.open("data.txt", "r+") do |file| content = file.read file.seek(0, IO::SEEK_SET) # ファイルポインタを先頭に移動 file.write("Overwritten!\n" + content)
end
w+読み書きモード。ファイルを上書きまたは新規作成。
File.open("temp.txt", "w+") do |file| file.puts "Line 1" file.rewind # ポインタを先頭に戻す puts file.read # "Line 1\n" が出力される
end
a+読み書きモード。ファイルの末尾から開始または新規作成。
File.open("log.txt", "a+") do |file| file.puts "New log entry at #{Time.now}" file.rewind puts "Current log content:\n#{file.read}"
end

ファイル・ディレクトリ操作 (File, Dir, FileUtils)

目的メソッド例コード例
存在確認File.exist?(path), Dir.exist?(path), File.file?(path), File.directory?(path)
puts File.exist?("my_file.txt")
puts Dir.exist?("/tmp")
ファイル情報取得File.size(path), File.mtime(path), File.basename(path), File.dirname(path), File.extname(path)
puts File.size("my_file.txt") rescue 0
puts File.basename("/path/to/file.rb") # "file.rb"
puts File.dirname("/path/to/file.rb") # "/path/to"
puts File.extname("/path/to/file.rb") # ".rb"
ディレクトリ操作Dir.mkdir(path), Dir.rmdir(path), Dir.entries(path), Dir.glob(pattern), Dir.pwd, Dir.chdir(path)
# Dir.mkdir("new_dir") unless Dir.exist?("new_dir")
puts Dir.entries(".").inspect # カレントディレクトリの内容
puts Dir.glob("*.rb").inspect # カレントの .rb ファイル一覧
puts Dir.pwd # カレントディレクトリ表示
ファイル/ディレクトリ操作 (高レベル)FileUtils モジュール (require 'fileutils' が必要)
require 'fileutils'
# FileUtils.cp("source.txt", "destination.txt") # コピー
# FileUtils.mv("old_name.txt", "new_name.txt") # 移動/リネーム
# FileUtils.rm("temp.txt") # 削除 (ファイル)
# FileUtils.rm_r("dir_to_remove") # 削除 (ディレクトリとその中身)
# FileUtils.mkdir_p("path/to/nested/dir") # 再帰的にディレクトリ作成

例外処理

エラー発生時の処理を記述します。

beginrescueelseensureend

begin # 例外が発生する可能性のある処理 result = 10 / 0 # ZeroDivisionError が発生 puts "計算結果: #{result}" # ここは実行されない
rescue ZeroDivisionError => e # ZeroDivisionError が発生した場合の処理 puts "ゼロで除算しようとしました: #{e.message}" puts e.backtrace.join("\n") # バックトレース表示
rescue ArgumentError => e # ArgumentError が発生した場合の処理 puts "引数エラー: #{e.message}"
rescue StandardError => e # 一般的なエラーを捕捉 (省略した場合のデフォルト) puts "予期せぬエラーが発生しました: #{e.class} - #{e.message}"
else # 例外が発生しなかった場合の処理 (rescue節のどれも実行されなかった場合) puts "処理は正常に完了しました。"
ensure # 例外の発生有無に関わらず、必ず実行される処理 puts "クリーンアップ処理などを実行します。"
end

例外の発生 (raise)

def check_age(age) if age < 0 raise ArgumentError, "年齢が負の値です: #{age}" # エラーメッセージ付きで発生 elsif age < 18 raise "未成年です" # RuntimeError を発生 (メッセージのみ) else puts "成人です" end
end
begin check_age(-5)
rescue ArgumentError => e puts "エラー捕捉: #{e.message}"
end
begin check_age(15)
rescue RuntimeError => e puts "エラー捕捉: #{e.message}"
end

retry

rescue節の中で使うと、begin節の最初から処理をやり直します。無限ループにならないよう注意が必要です。

attempts = 0
max_attempts = 3
begin attempts += 1 puts "#{attempts}回目の試行..." # 失敗する可能性のある処理 raise "接続エラー" if attempts < max_attempts puts "成功しました!"
rescue => e puts "エラー発生: #{e.message}" if attempts < max_attempts puts "リトライします..." sleep(1) # 少し待つ retry # begin からやり直し else puts "最大試行回数に達しました。" end
end

メソッド全体での例外処理 (暗黙のbegin)

メソッド定義全体が暗黙的にbeginブロックで囲まれているとみなせます。

def process_file(filename) file = File.open(filename) # 処理... puts "ファイル処理完了: #{filename}"
rescue Errno::ENOENT puts "ファイルが見つかりません: #{filename}"
ensure file&.close # メソッド終了時に必ず呼ばれる
end
process_file("existent.txt")
process_file("non_existent.txt")

その他

その他の重要な要素や便利な機能です。

項目説明コード例
シンボル (Symbol):symbol_name の形式。文字列より軽量で、ハッシュのキーや状態を表すのに使われる。内部的には整数。
status = :pending
puts status == :pending # true
config = { db_host: "localhost", db_port: 5432 }
範囲オブジェクト (Range)連続した値の範囲を表す。.. は終端を含む、... は終端を含まない。
numbers = 1..5 # 1, 2, 3, 4, 5
exclusive = 1...5 # 1, 2, 3, 4
puts numbers.include?(3) # true
puts exclusive.include?(5) # false
('a'..'d').each { |c| print c } # abcd
Proc オブジェクトコードブロックをオブジェクト化したもの。proc, lambda, -> (stabby lambda) で生成。&でブロックとProcを相互変換。
# Proc生成
my_proc = Proc.new { |x| puts "Proc: #{x}" }
my_lambda = lambda { |x| puts "Lambda: #{x}" }
stabby = ->(x) { puts "Stabby: #{x}" }
# 呼び出し
my_proc.call(10)
my_lambda.call(20)
stabby.(30) # .() でも呼び出せる
# lambdaは引数の数に厳密、Procは寛容
# my_lambda.call # エラー
# my_proc.call # エラーにならない (nil が渡される)
# & ブロック引数
def run_block(&block) puts "Running block..." block.call("from method") if block
end
run_block { |msg| puts "Block executed: #{msg}" }
run_block(&my_proc) # Procオブジェクトをブロックとして渡す
日時 (Time, Date, DateTime)日時を扱うクラス。DateDateTime を使うには require 'date' が必要。
require 'date'
now = Time.now
puts "Time: #{now}"
puts "Year: #{now.year}"
today = Date.today
puts "Date: #{today}"
puts "Next day: #{today + 1}"
dt_now = DateTime.now
puts "DateTime: #{dt_now}"
puts "Hour: #{dt_now.hour}"
# 書式設定
puts now.strftime("%Y-%m-%d %H:%M:%S") # "2025-04-03 09:12:00" (例)
requireload他のRubyファイルやライブラリを読み込む。require は一度だけ読み込む(同じファイルを再度 require しても無視される)。load は毎回読み込む。拡張子 .rbrequire では省略可能。
require 'set' # 標準ライブラリのSetクラスを使う
# require_relative 'my_module' # 同じディレクトリ内のmy_module.rbを読み込む
# load 'config.rb' # config.rbを読み込む (実行するたびに再読み込み)
ブロック (Block)do...end または {...} で囲まれたコードの塊。メソッドに渡され、yield で実行されるか、& でProcオブジェクト化される。
# each メソッドにブロックを渡す
[1, 2, 3].each do |n| puts n * 10
end
# map メソッドにブロックを渡す (一行なので {} を使用)
squares = [1, 2, 3].map { |n| n**2 }
puts squares.inspect # [1, 4, 9]

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です