Ruby・Ruby on Rails チートシート

みなさんRubyでの開発経験はありますか>？RubyのwebフレームワークであるRuby on Railsを使うと結構簡単に作成することも可能です．本記事ではRubyの基本的な文法からRailsを使ったWeb開発の手法まで広く紹介します．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/0e1db789-43c4-4596-73d1-9bbf509fc43c.png)


# 他のチートシート
git/gh コマンド(gitコマンド以外にもgitの概念も書いてあります)

https://qiita.com/JavaLangRuntimeException/items/6b46551f56e0def76eba

lazygit

https://qiita.com/JavaLangRuntimeException/items/42087d09728d5739d73d

Docker コマンド(dockerコマンド以外にもdockerの概念の記事へのリンクもあります)

https://qiita.com/JavaLangRuntimeException/items/21f7c7bf3d143f821697

ステータスコード

https://qiita.com/JavaLangRuntimeException/items/ab1bc7b976ed2dfad91c

TypeScript

https://qiita.com/JavaLangRuntimeException/items/5894391c08e0d8e28389

Go/Gorm

https://qiita.com/JavaLangRuntimeException/items/d388717fc1436bc3ec9d


SQL

https://qiita.com/JavaLangRuntimeException/items/f038fbaccdd92fb0308a

Vim

https://qiita.com/JavaLangRuntimeException/items/0c68ab96ea198e0a7294

プルリクエスト・マークダウン記法チートシート

https://qiita.com/JavaLangRuntimeException/items/329eb92a47a07ff4dde8

ファイル操作コマンドチートシート

https://qiita.com/JavaLangRuntimeException/items/16f244606a73f7d106e4

VSCode Github Copilot拡張機能

https://qiita.com/JavaLangRuntimeException/items/be13dc3a346cf6e5ee44

OpenAI Assistants API

https://qiita.com/JavaLangRuntimeException/items/1a1abc01e8d7d05dce93

Github API

https://qiita.com/JavaLangRuntimeException/items/4f3551c31679233219ac



# 他のシリーズ記事
**TypeScriptで学ぶプログラミングの世界**
プログラミング言語を根本的に理解するシリーズです．

https://qiita.com/JavaLangRuntimeException/items/cadf49bb419076819963

**情報処理技術者試験合格への道[IP・SG・FE・AP]**
情報処理技術者試験に出題されるコンピュータサイエンス用語の紹介や単語集

https://qiita.com/JavaLangRuntimeException/items/991be402099542ccb936

**IAM AWS User クラウドサービスをフル活用しよう！**
AWSのサービスを例にしてバックエンドとインフラ開発の手法を説明するシリーズです．

https://qiita.com/JavaLangRuntimeException/items/371a334f5a6e07035db5

**AWS UserのGCP浮気日記**
GCPの様子をAWSと比較して考えてみるシリーズ

https://qiita.com/JavaLangRuntimeException/items/527d99e774165a763180

**Project Gopher: Unlocking Go’s Secrets**
Go言語や標準ライブラリの深掘り調査レポートです．

https://qiita.com/JavaLangRuntimeException/items/dc45b412d3fbd2ccb9e8

**Gopher’s Journey: Exploring TCP Protocol**
Goを用いてTCPプロトコルを探求 & 作成するシリーズです．

https://qiita.com/JavaLangRuntimeException/items/38091220106d86651d2b


# Rubyの概要
Rubyはまつもとゆきひろ氏(Matz)によって1990年代に開発されたオブジェクト指向スクリプト言語である. 文法がシンプルで読みやすいことが大きな特徴で, 動的型付けを採用しているため, コードの記述量が少なく直感的に開発を進められる. また, Rubyの理念として「プログラマの幸せを考えたプログラミング言語」という方針が掲げられており, 使い心地のよい言語設計がなされている. Webアプリケーション開発はもちろん, コマンドラインでのスクリプトやインフラ管理, テスト自動化など, 幅広い分野で利用されている.

# Rubyの主な特徴

**1. すべてがオブジェクト**
整数や文字列, trueやnilといった値まで含め, Rubyではあらゆるものがオブジェクトである. 統一的な書き方が可能であり, どの値にもメソッドを呼び出せる. 例えば整数に対してもメソッドを呼び出せる点は, 他の言語とは違うRubyの特徴である.

```rb
num = 10
puts num.class        # => Integer
puts num.next         # => 11
puts num.to_s         # => "10"

str = "Hello"
puts str.class        # => String
puts str.upcase       # => "HELLO"
puts str.include?("H")  # => true
```
**2. 動的型付け**
変数に型宣言を行わず, 代入されたオブジェクトの型が自動的に適用される. 同じ変数に数値を代入したり文字列を代入したりできる柔軟さがある一方で, 静的型チェックがないため, 実行前に型の不整合を検出しにくい. テストや型解析ツール(Sorbetなど)を組み合わせることで, 大規模開発でも十分に運用できる.

```rb
value = 100
puts value.class  # => Integer

value = "hundred"
puts value.class  # => String
```
**3. オブジェクト指向設計のしやすさ** 
Rubyにはクラスやモジュール, 継承, ミックスインといった仕組みがあり, オブジェクト指向を自然に表現できる. また, メタプログラミングにより動的にメソッドを生成するなど高度な機能も備える.

```rb
class Animal
  def speak
    "..."
  end
end

class Dog < Animal
  def speak
    "Woof!"
  end
end

dog = Dog.new
puts dog.speak  # => "Woof!"

# モジュールをミックスイン
module Greeting
  def greet
    "Hello from #{self.class}"
  end
end

class Person
  include Greeting
end

alice = Person.new
puts alice.greet  # => "Hello from Person"

# メタプログラミング例: 動的にメソッドを作る
class DynamicExample
  [:foo, :bar, :baz].each do |name|
    define_method(name) do
      "Method #{name} called."
    end
  end
end

demo = DynamicExample.new
puts demo.foo  # => "Method foo called."
puts demo.bar  # => "Method bar called."
puts demo.baz  # => "Method baz called."
```
**4. 豊富なライブラリとフレームワーク**  
標準ライブラリはもちろん, インターネット上には数多くのGemが公開されており, Web開発におけるRuby on RailsやSinatra, インフラ管理におけるChef, テストにおけるRSpecなど, 多岐にわたるフレームワークが存在する. これらを活用することで, 開発生産性を大幅に高めることができる.

Rails風のイメージ
```rb
# Railsの場合, コントローラ内で以下のようなコードを書き,
# Active Recordを使ってDBとやりとりすることが可能.
class UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
  end
end

# RSpecを使ったテストの例
RSpec.describe "Sample test" do
  it "tests if 2+3 equals 5" do
    expect(2+3).to eq(5)
  end
end
```
**5. DSL(Domain Specific Language)の構築が容易**
Rubyの文法はカッコの省略やブロック構文などが柔軟であり, 人間が読み書きしやすいDSLを作るのに向いている. RakeやChefなどはRubyで書かれたDSLの代表例であり, コードがまるで設定ファイルのように読みやすい.
```rb
# Rakefile (ビルドタスクのDSL)
task :hello do
  puts "Hello from Rake task"
end

desc "Sample task with a parameter"
task :greet, [:name] do |_task, args|
  name = args[:name] || "Ruby"
  puts "Hello, #{name}!"
end

# コマンドラインで以下のように実行
# rake hello
# rake greet[Alice]
```
**6. ガーベジコレクション(GC)の採用**
RubyにはGC(Garbage Collection)があり, 不要になったオブジェクトを自動的にメモリから解放してくれる. これによりメモリ管理の煩雑さを軽減し, バグの原因となるメモリリークを起こしにくい. 開発者はビジネスロジックの実装に集中しやすくなる.

```rb
# メモリ管理のコードを書く必要がない
def create_lots_of_strings
  100.times do |i|
    s = "String number #{i}"
    # このスコープを抜けると, sへの参照がなくなるためGCの対象となる
  end
end

create_lots_of_strings
puts "Finished creating strings"
```
このように, Rubyはプログラマが心地よく開発できるよう設計されており, 幅広い分野で活躍することができる. 静的型付き言語にはない柔軟性と, 豊富なライブラリが相まって, さまざまなニーズに応えられる点が大きな魅力である.


# Rubyを学ぶ意義
Rubyを学ぶことで, 直感的なコードの書き方を身につけながら, オブジェクト指向プログラミングへの理解を深めることができる. また, Webアプリケーション開発においてはRuby on Railsという強力なフレームワークがあるため, サービス開発の立ち上げがスピーディに行える. テストフレームワークや自動化ツールなどを駆使して, 開発効率と保守性を高める手法も合わせて習得できる. 「プログラマの幸せを願う言語設計」が体現されており, 一度使うと他の言語でも同様の快適さを追求したくなる, そんな魅力を持っている.

# Rubyの歴史や用途
Rubyは1995年に初めて公開され, 当初は日本国内で徐々にユーザを増やしていた. 2004年にRuby on Railsが登場すると, 英語圏を中心に世界的な注目を集めるようになり, Web開発の分野で急速に普及した. その後, Rails以外のフレームワークやライブラリも充実していき, インフラ管理(Chef), テストツール(RSpec, Minitest), 構成管理など, 多方面で利用されている. 現在でもRuby 3以降のバージョンアップが続いており, 並列処理やパフォーマンス向上のための機能追加が活発に行われている.

# Rubyを実行してみよう
Rubyでファイルを実行するときは, 
```bash
ruby スクリプト名.rb
```
と入力する. コードをirb(Interactive Ruby)で試してみる場合は, 
```bash
irb
```
を実行するだけで対話型シェルが起動し, 一行ずつ入力したコードを即座に評価して結果を得られる. 以下のように数値演算を試すことができる.

```bash
irb(main):001:0> 2 + 3
=> 5
irb(main):002:0> "Ruby".upcase
=> "RUBY"
```
このように, スクリプトファイルで書く前に動作確認を手軽に行うことが可能である.

# RubyでHelloWorld
Rubyでは最もシンプルなプログラムとして, 画面に"Hello World"と出力するスクリプトを作ることができる. 次の例をhello.rbというファイルに記述したとする.

```hello.rb
puts "Hello World"
```
:::note info
**Rubyでは出力方法として主にpとputsの2つがある** 
putsは人間が読みやすい形で出力を行い, 文字列の場合はクォートを省略して表示する. 一方pはデバッグ用途に適しており, 文字列はクォート付きで出力され, 配列は[1, 2, 3]のように構造を含めた形で表示される. また, putsがnilを返すのに対し, pは入力された値をそのまま返すため, メソッドチェーンで利用できるという特徴がある.
```rb
text = "Hello"
array = [1, 2, 3]
nil_value = nil

puts text      # => Hello
puts array     # => 1
               #    2
               #    3
puts nil_value # => （空行を出力）

p text         # => "Hello"
p array        # => [1, 2, 3]
p nil_value    # => nil
```
:::
ファイルを保存後, 端末で以下を実行する.
```bash
ruby hello.rb
```
すると, 画面に"Hello World"という文字列が表示される. この一行のコードからも分かる通り, Rubyはシンプルで分かりやすい文法を備えている.

ここまでで主な概要は示したが, 実際の開発では変数やデータ型, 制御構文, クラスの定義, メソッドの記述などを組み合わせ, より複雑なプログラムを構築していく. Ruby独自の柔軟な書き方を活かすことで, 開発者に優しいコードを多く書ける点が特徴である.

# Rubyの基本文法
## 変数宣言
Rubyでは変数の型を明示的に指定する必要がなく, 代入した値に基づいて動的に型が決定される. 変数名には英数字とアンダースコアが使え, 小文字で始まるのが一般的である. 例えば, greeting, number, is_ruby_funという3つの変数を以下のように定義できる.

```rb
greeting = "こんにちは"
number = 42
is_ruby_fun = true

puts greeting
puts number
puts is_ruby_fun
```

上記の例では, greetingには文字列(String), numberには整数(Integer), is_ruby_funには真偽値(TrueClass)が代入されている. Rubyではこれらの変数を別の型の値に再代入することもできる.

```rb
number = 42
puts number.class  # => Integer

number = "四十二"
puts number.class  # => String
```
このように一度整数を代入した変数に, 後から文字列を代入しても問題なく実行できる. ただし, 動的型付けゆえに誤った型同士の演算を実行時に発見するケースがあるため, 大規模な開発ではテストをしっかり書いたり, 型解析ツールを導入したりすることが多い.

## 定数
Rubyにおいて定数は, 変数名の先頭が大文字で始まる変数であり, 再代入を行わないことが原則とされるである. 定数はプログラム全体で変更されるべきでない値を保持するために用いられるであるが, 内部に格納されたオブジェクトがミュータブルな場合, その状態が変更される可能性があるである. 再代入や内部状態の変更に対しては警告が表示されるが, 強制的なエラー発生には至らない場合もある.

### freeze
freezeはRubyの組み込みメソッドであり, オブジェクトに対して呼び出すことによりその状態を完全に固定するための機能である. freezeされたオブジェクトは変更不可能となり, 配列やハッシュなどで新しい要素の追加や既存の要素の変更を試みると実行時エラーが発生する. このため, オブジェクトの内容を厳密に不変とする必要がある場合に利用される.

:::note info
**定数とfreezeの違い**
Rubyにおける定数は, 変数名の先頭が大文字であり, 再代入を原則として禁止する規約である. しかし, 定数自体は不変なオブジェクトを意味するわけではなく, 定数に格納されたオブジェクトがミュータブルな場合, その内部状態は変更可能である.

一方, freezeはオブジェクトに対して呼び出し, そのオブジェクトの状態を変更不可能にするメソッドである. freezeされたオブジェクトに対する変更操作は実行時エラーを発生させるため, 真の不変性が保証される.

**1. 不変性の範囲**  
   定数は変数として再代入を防ぐための規約であるが, 内部に格納されたオブジェクトがミュータブルな場合, 状態変更が可能であるである. 対して, freezeはそのオブジェクト自体を不変化させるため, いかなる変更も許容しないである.

**2. 警告とエラーの違い**  
   定数への再代入を試みると, Rubyは警告を表示するに留まり, 強制的に実行を停止するものではないである. しかし, freezeされたオブジェクトに対して変更操作を行うと, 実行時にエラー (たとえばTypeError) が発生するである.

**3. 使用目的**  
   定数は, プログラム中で変わらない値を管理するための命名規約として用いられるである. これに対し, freezeはオブジェクトの状態そのものの不変性を厳密に保証するための手段であるである. 必要に応じて定数で定義したオブジェクトにfreezeを適用し, オブジェクトの内容が意図せず変更されることを防止することが推奨される.
```rb
# 定数として配列を定義する
MY_ARRAY = [1, 2, 3]
# 定数MY_ARRAYへの再代入は警告されるが, 内部の内容は変更可能である
MY_ARRAY << 4    # MY_ARRAYは[1, 2, 3, 4]となるである

# 定数として定義した配列にfreezeを適用する
MY_FROZEN_ARRAY = [1, 2, 3].freeze
# 以下の操作は実行時エラーとなる
MY_FROZEN_ARRAY << 4   # => RuntimeError: can't modify frozen Array
```

定数は, 変数名の先頭が大文字であることで再代入を避ける規約であるが, 内部のオブジェクトがミュータブルな場合はその内容が変更される可能性がある. これに対し, freezeはオブジェクト自体を不変化させ, 変更操作に対して厳密にエラーを発生させるため, 真の不変性を求める場合に使用される. 用途に応じて, 定数としての利用とfreezeによる不変化の適用を使い分けることが推奨される.
:::

## 演算子(算術, 比較など)
Rubyでは算術演算子や比較演算子を用いて数値演算や条件式を記述できる.

### 算術演算子
```
+ (足し算),
- (引き算), 
* (掛け算), 
/ (割り算), 
% (剰余), 
** (累乗)
```
```rb
x = 10
y = 3

sum = x + y       # 10 + 3  => 13
difference = x - y  # 10 - 3  => 7
product = x * y   # 10 * 3  => 30
quotient = x / y  # 10 / 3  => 3  (整数同士の割り算の場合, 小数点以下は切り捨て)
remainder = x % y # 10 % 3  => 1
power = x ** y    # 10 ** 3 => 1000

puts sum
puts difference
puts product
puts quotient
puts remainder
puts power
```
なお, x / yが3ではなく3.3333...を期待する場合は, 浮動小数点(Float)の値を使う.

```rb
x = 10.0  # float
y = 3

quotient = x / y  # 10.0 / 3 => 3.3333333333333335
puts quotient
```
### 比較演算子
==, !=, >, <, >=, <=, <=>, ===などがある. 代表的なものを紹介する.

```rb
a = 5
b = 7

puts a == b   # => false
puts a != b   # => true
puts a < b    # => true
puts a > b    # => false
puts a <=> b  # => -1  (aがbより小さいので-1)
```
#### 宇宙船演算子<=>
a <=> bは通称「宇宙船演算子」と呼ばれ, 左辺が右辺より小さい(a < b)場合は-1, 等しい場合(a == b)は0, 大きい場合(a > b)は1を返す. ソートのアルゴリズムなどで利用されることがある.
```rb
# 基本的な数値の比較
puts 1 <=> 1  # => 0  (等しい)
puts 1 <=> 2  # => -1 (左が小さい)
puts 2 <=> 1  # => 1  (左が大きい)

# 配列のソートでの使用例
fruits = ['banana', 'apple', 'cherry']
sorted_fruits = fruits.sort { |a, b| a <=> b }
p sorted_fruits  # => ["apple", "banana", "cherry"]

# 文字列の比較
puts "apple" <=> "banana"   # => -1
puts "cherry" <=> "banana"  # => 1
puts "apple" <=> "apple"    # => 0

# 浮動小数点数の比較
puts 1.5 <=> 2.5  # => -1
puts 2.5 <=> 2.5  # => 0
puts 3.5 <=> 2.5  # => 1

# カスタムクラスでの使用例
class Person
  include Comparable
  attr_reader :name, :age

  def initialize(name, age)
    @name = name
    @age = age
  end

  def <=>(other)
    age <=> other.age
  end
end

alice = Person.new("Alice", 20)
bob = Person.new("Bob", 25)
puts alice <=> bob  # => -1
```

#### ===演算子
===演算子はcase式での比較やRangeオブジェクトの一致判定などに使われる.

```rb
range = (1..10)
puts range === 5   # => true
puts range === 11  # => false
```

```rb
case "hello"
when String  # String === "hello" が評価される
  puts "文字列です"
end
```

:::note info
**従来の==演算子と===演算子を比較**
===を使う場合
```rb
case age
when 0..12
  "子供"
when 13..19
  "十代"
end
```
従来の比較(==)演算子を使う場合
```rb
if age >= 0 && age <= 12
  "子供"
elsif age >= 13 && age <= 19
  "十代"
end
```
:::
## データ型(数値, 文字列, 配列, ハッシュなど)
Rubyではさまざまな種類のデータをオブジェクトとして扱う. よく使われる代表的なデータ型を以下に示す.

### 1. 数値(Integer, Float)
整数(Integer)と浮動小数点数(Float)があり, 数値リテラルとして代入する. 整数が非常に大きくなると, 自動的にBigInteger扱いとなり, オーバーフローが発生しないのが特徴である.

```rb
int_num = 123
float_num = 3.14

puts int_num.class   # => Integer
puts float_num.class # => Float

big_num = 999999999999999999999999999999
puts big_num.class   # => Integer (大きい値でもIntegerになる)
```
### 2. 文字列(String)
ダブルクォートとシングルクォートで表記方法が異なり, ダブルクォート内では式展開(#{...})や特殊文字のエスケープが有効になる. シングルクォートではそれらは行われない.

```rb
str_double = "Ruby\nLanguage"
str_single = 'Ruby\nLanguage'
puts str_double  # => 改行を含む
puts str_single  # => バックスラッシュ付きで出力される

name = "Alice"
puts "Hello, #{name}"  # => "Hello, Alice"
```
### 3. 配列(Array)
Rubyの配列は順序付きの要素を格納するコレクションである. 要素には文字列, 数値, 真偽値, さらには他の配列やハッシュなど, あらゆるオブジェクトを入れることができる.

#### 配列の作成と初期化
配列は角括弧[]で作成し, あらかじめ要素を指定する方法と空の配列を用意して後から要素を追加する方法がある.

```rb
colors = ["red", "green", "blue"]
puts colors.inspect  # => ["red", "green", "blue"]

empty_arr = []
puts empty_arr.inspect  # => []

mixed_arr = [1, "two", :three, [4, 5]]
puts mixed_arr.inspect  # => [1, "two", :three, [4, 5]]

arr = []
puts arr.class # => Array
```

:::note info
**配列の出力におけるpとputsの違い**
```rb
str = "Hello"
num = 123
arr = [1, 2, 3]
nil_val = nil

# puts：人が読みやすい形で出力
puts str      # => Hello
puts num      # => 123
puts arr      # => 1
              #    2
              #    3
puts nil_val  # => （空行を出力）

# p：デバッグ向き。オブジェクトの詳細情報を出力
p str      # => "Hello"     （文字列はクォートつきで出力）
p num      # => 123
p arr      # => [1, 2, 3]   （配列は1行で構造も含めて出力）
p nil_val  # => nil         （nilもちゃんと表示）
```
:::
#### 要素のアクセス
インデックス(添字)を指定して要素を取得する. 先頭要素は0番目, 負のインデックスで後ろから数えられる.

```rb
colors = ["red", "green", "blue", "yellow"]
puts colors[0]         # => "red"
puts colors[2]         # => "blue"
puts colors[-1]        # => "yellow"
puts colors[1..2].inspect  # => ["green", "blue"]
```
#### 要素の追加と削除(push, pop, shift, unshift)
pushと<<は配列の末尾に要素を追加し, popは末尾から要素を取り出す. shiftとunshiftで先頭要素を取り出したり追加したりできる.

```rb
numbers = [1, 2, 3]
numbers.push(4)      # => [1, 2, 3, 4]
numbers << 5         # => [1, 2, 3, 4, 5]
popped = numbers.pop  # => 5
puts popped          # => 5
puts numbers.inspect # => [1, 2, 3, 4]

numbers.shift        # => 1
numbers.unshift(0)   # => [0, 2, 3, 4]
puts numbers.inspect # => [0, 2, 3, 4]
```
#### 任意の位置への挿入と削除
insertメソッドを使って特定のインデックスへ要素を追加し, delete_atで特定インデックスの要素を削除できる.

```rb
arr = [10, 20, 40]
arr.insert(2, 30)  # => [10, 20, 30, 40]
arr.delete_at(0)   # => 10(削除された値)
puts arr.inspect   # => [20, 30, 40]
```
#### 要素の一部を取得や切り出し(slice, values_at)
範囲指定やslice, values_atなどで配列の一部を取り出せる.

```rb
arr = ["a", "b", "c", "d", "e"]
puts arr.slice(1, 3).inspect  # => ["b", "c", "d"]
puts arr[1..3].inspect        # => ["b", "c", "d"]
puts arr.values_at(0, 2, 4).inspect  # => ["a", "c", "e"]
```
#### 配列の連結や結合(concat, +)
配列同士を結合するにはconcat(破壊的)や+演算子(非破壊的)を使う.

```rb
arr1 = [1, 2]
arr2 = [3, 4]
arr1.concat(arr2)
puts arr1.inspect  # => [1, 2, 3, 4]

arr3 = [1, 2]
arr4 = [3, 4]
arr5 = arr3 + arr4
puts arr3.inspect  # => [1, 2]
puts arr5.inspect  # => [1, 2, 3, 4]
```

#### 繰り返し処理(each, each_with_indexなど)
配列の要素を順番に処理したい場合はeachやeach_with_indexを使う.

```rb
colors = ["red", "green", "blue"]
colors.each do |color|
  puts "Color: #{color}"
end

colors.each_with_index do |color, index|
  puts "#{index}: #{color}"
end
```

#### 要素の変換(map, collect)
mapやcollectメソッドで各要素を変換した結果を新しい配列として返す.

```rb
nums = [1, 2, 3, 4]
squared = nums.map { |n| n * n }  # => [1, 4, 9, 16]
puts squared.inspect
```

#### 要素の絞り込み(select, reject, find)
selectはブロックがtrueを返す要素だけ残し, rejectはfalseを返す要素だけ残す. findは最初にマッチした要素を返す.

```rb
nums = [10, 15, 20, 25, 30]
bigger_than_20 = nums.select { |n| n > 20 }  
puts bigger_than_20.inspect # => [25, 30]

not_divisible_20 = nums.reject { |n| n % 20 == 0 }
puts not_divisible_20.inspect  # => [15, 25]

found = nums.find { |n| n >= 25 }  
puts found # => 25
```

#### 要素の探索(index, rindex, include?)
indexやrindexで検索を行い, include?で配列に要素が含まれるかどうかを判定する.

```rb
arr = ["apple", "banana", "cherry", "banana"]
puts arr.index("banana")   # => 1
puts arr.rindex("banana")  # => 3
puts arr.include?("cherry")  # => true
```

#### 配列の長さや要素数(length, size, count)
length, size, countは要素数を返し, countに引数を渡すとその値がいくつ含まれるかを数える.

```rb
arr = [1, 2, 2, 3]
puts arr.length    # => 4
puts arr.count     # => 4
puts arr.count(2)  # => 2
```

#### 並べ替え(sort, sort!)
sortは並び替えた新しい配列を返し, sort!は配列を破壊的に並び替える.

```rb
arr = [3, 1, 5, 2, 4]
sorted_arr = arr.sort
puts sorted_arr.inspect  # => [1, 2, 3, 4, 5]
puts arr.inspect         # => [3, 1, 5, 2, 4]

arr.sort!
puts arr.inspect         # => [1, 2, 3, 4, 5]
```

#### 重複やnil要素を除去(uniq, compact)
uniq, compactはそれぞれ重複要素やnil要素を取り除く. 破壊的メソッドとしてuniq!, compact!も存在する.

```rb
arr = [1, 2, 2, 3, nil, 3]
puts arr.uniq.inspect     # => [1, 2, 3, nil]
puts arr.inspect          # => [1, 2, 2, 3, nil, 3]
arr.uniq!
puts arr.inspect          # => [1, 2, 3, nil]
arr.compact!
puts arr.inspect          # => [1, 2, 3]
```

#### 文字列との変換(join, flatten)
joinは配列の要素を連結して文字列を作る. flattenで多次元配列を1次元化する.

```rb
arr = ["Ruby", "is", "fun"]
puts arr.join(" ")  # => "Ruby is fun"

multi_arr = [[1, 2], [3, 4, [5]]]
puts multi_arr.flatten.inspect  # => [1, 2, 3, 4, 5]
```

#### その他の便利メソッド(sum, sample, shuffle, combination, permutation, transpose, product)
sumで要素を合計でき, sampleでランダム要素を取得, shuffleで配列をランダムに並び替えられる. また, combinationやpermutationで組み合わせや順列を生成でき, transposeやproductなど行列計算やデカルト積にも対応する.

```rb
nums = [1, 2, 3, 4]
puts nums.sum                 # => 10
puts nums.sample             # => ランダムで1,2,3,4のいずれか
puts nums.shuffle.inspect     # => 要素がランダムに並び替えられた新配列
comb = nums.combination(2).to_a
puts comb.inspect            # => [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
perm = nums.permutation(2).to_a
puts perm.inspect            # => [[1, 2], [1, 3], ...

p1 = [1, 2]
p2 = ["A", "B"]
puts p1.product(p2).inspect  # => [[1, "A"], [1, "B"], [2, "A"], [2, "B"]]
```
Rubyの配列は非常に豊富なメソッドを備えており, 各種の追加・削除, 検索, 加工が簡単に行える. 特にイテレータメソッドや変換メソッドを活用すると, 短いコードで複雑な処理を表現できる.

#### 多次元配列
多次元配列とは配列の中に配列が入れ子になった構造で，行列やテーブルのようなデータを表現するのに適している．要素へのアクセスはarray[n][m]のように複数の角括弧を使い，最初の添字で外側の配列の位置を，次の添字で内側の配列の位置を指定する．
```rb
# 2次元配列の作成と操作
matrix = [
  [1, 2, 3],  # インデックス[0]の配列
  [4, 5, 6],  # インデックス[1]の配列
  [7, 8, 9]   # インデックス[2]の配列
]

# 要素へのアクセス
puts matrix[1][2]     # => 6  (2行目の3番目の要素)
puts matrix[0][0]     # => 1  (1行目の1番目の要素)
puts matrix[2][2]     # => 9  (3行目の3番目の要素)

# 配列の変更
matrix[1][1] = 10     # 真ん中の要素を変更
p matrix              # => [[1, 2, 3], [4, 10, 6], [7, 8, 9]]

# 行の追加
matrix.push([10, 11, 12])
p matrix              # => [[1, 2, 3], [4, 10, 6], [7, 8, 9], [10, 11, 12]]

# 様々な作成方法
# Array.newを使用した初期化
matrix2 = Array.new(3) { Array.new(3, 0) }
p matrix2            # => [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

# 各要素に対する操作
matrix.each do |row|
  row.each do |element|
    print "#{element} "
  end
  puts  # 改行
end

# 配列の変換
# 各要素を2倍にする
doubled = matrix.map do |row|
  row.map { |element| element * 2 }
end
p doubled

# 3次元配列の例
cube = [
  [[1, 2], [3, 4]],
  [[5, 6], [7, 8]]
]
puts cube[1][0][1]    # => 6  (2層目の1行目の2番目の要素)

# 特定の値で初期化された大きな配列
# 5x5のチェス盤のような配列を作成
board = Array.new(5) { Array.new(5, "*") }
p board
```

### 4. ハッシュ(Hash)
キーと値をセットで扱うデータ構造で, Pythonの辞書型やJavaScriptのオブジェクトに相当する. キーをシンボル(:nameのような形式)や文字列, 数値など様々なオブジェクトにできる.

```rb
person = { name: "Alice", age: 20 }
puts person[:name]         # => "Alice"
person[:job] = "Engineer"  # 新しいキーを追加
puts person.inspect        # => {:name=>"Alice", :age=>20, :job=>"Engineer"}
```

:::note info
**文字列とシンボルの主な違い**

**1. 不変性**
   シンボルは一度生成されると内容が変更されない不変なオブジェクトである. 同一のシンボルはプログラム全体で一つのオブジェクトとして扱われるため, メモリ効率も良い. 一方, 文字列は基本的に可変であり, 後から内容を変更することが可能である.

**2. メモリ効率と速度**  
   シンボルは同一のシンボルが複数回利用される場合, 既に生成されたオブジェクトが再利用されるためメモリ効率が良く, ハッシュのキーとして高速なアクセスが可能である. 文字列は同じ内容であっても都度新しいオブジェクトが生成される可能性があるため, 多用するとメモリに負荷がかかる場合がある.

**3. 使用目的**  
   シンボルは主に定数的な識別子として利用されることが推奨され, ハッシュのキーや状態管理のために使われるである. 文字列はユーザーからの入力や出力の表示など, テキストデータとして使用されることが多い.

**定義方法**

- 文字列は, ダブルクォーテーション(" ")またはシングルクォーテーション(' ')で囲んで定義する  
```rb
my_string = "Hello, Ruby"  
# または  
my_string = 'Hello, Ruby'
```
- シンボルはコロン(:)を先頭に付けて定義する
```rb
my_symbol = :hello
```

Rubyにおいて, 文字列は可変なテキストデータを扱うオブジェクトであり, シンボルは不変かつ唯一の識別子として利用されるオブジェクトである. そのため, ハッシュのキーなど頻繁に利用する場合は, メモリ効率やパフォーマンスの観点からシンボルを採用することが推奨される.
:::

#### 文字列キーのハッシュ
```rb
scores = { "math" => 90, "english" => 85 }
puts scores["math"]   # => 90
```

#### eachメソッドでキーと値を取得
```rb
scores.each do |subject, point|
  puts "#{subject}: #{point}"
end
```
#### ハッシュのメソッド
```rb
puts person.keys.inspect   # => [:name, :age, :job]
puts person.values.inspect # => ["Alice", 20, "Engineer"]
```
キーの順序はRuby 1.9以降維持されるようになっており, 入れた順番通りに取り出すことができる.

以上のように, Rubyでは一つの変数に文字列や数値, 配列やハッシュといった様々な型を代入し, それらを組み合わせることで柔軟なプログラムを構築する. 動的型付けならではの書きやすさと, 豊富なメソッドが提供される標準ライブラリのおかげで, 少ないコード量で多様な処理を実装できる点が大きな利点である.

## 条件分岐(if...else文, case文, ?演算子, ネスト)
Rubyにはさまざまな条件分岐が用意されており, プログラムの流れを制御しやすい. 代表的な構文を順に見ていく.

### if...else文
条件式がtrueならばif節の処理が, falseならばelse節の処理が実行される. さらに複数の条件を判定したい場合はelsifを挟んで連鎖的にチェックできる.

```rb
score = 85
if score >= 90
  puts "Excellent"
elsif score >= 70
  puts "Good"
else
  puts "Needs Improvement"
end
```
上記ではscoreが90以上なら"Excellent"を, 70以上なら"Good"を, それ以外なら"Needs Improvement"を表示する. また, elsifは何度でも続けられるが, 条件分が多いときは可読性に注意が必要である.

#### ネストしたif文
if文の中にさらにif文を入れることもできる. しかし, 深すぎるネストは可読性を下げる原因となるため, 条件分岐が複雑になる場合は別の手段(早期returnやcase文の活用など)を検討する.

```rb
score = 78
if score >= 70
  if score >= 90
    puts "Excellent"
  else
    puts "Good"
  end
else
  puts "Needs Improvement"
end
```

この例ではまずscoreが70以上かを判定し, 70以上なら今度は90以上かどうかを判定している.

### unless文
ifの逆の条件である, "もし～でなければ" という意味を持つunless文もある. if文で否定条件を書くよりも可読性が高くなる場合がある.

```rb
is_logged_in = false
unless is_logged_in
  puts "ログインしてください"
end
```

上記の例はif !is_logged_inと書くのと同等である.

### case文
複数の条件分岐を分かりやすく書ける構文としてcase文がある. 判定したいオブジェクトや値をcaseのあとに置き, when節で各条件を記述する.

```rb
signal = "yellow"
case signal
when "red"
  puts "Stop"
when "green"
  puts "Go"
when "yellow"
  puts "Caution"
else
  puts "Unknown signal"
end
```
signalの値に応じて出力を切り替えている. else節に相当するものはcase文ではwhen以外のパターンにマッチしなかった場合の処理を定義できる.

#### case文の拡張例
Rubyでは===演算子を活用して, より複雑な判定をcase文で行うこともできる. 例えば数値がある範囲に含まれているかどうかを調べるといった使い方が可能である.

```rb
score = 68
case score
when 0..59
  puts "Failed"
when 60..79
  puts "Passed"
when 80..89
  puts "Good"
when 90..100
  puts "Excellent"
else
  puts "Out of range"
end
```
ここではスコア(score)の値が0から59の範囲であれば"Failed", 60から79なら"Passed"というように, 範囲指定をシンプルに書ける.

### ?演算子(三項演算子)
if...else文を簡潔に書きたい場合は?演算子を使う. "条件式 ? 真の場合 : 偽の場合"という形で1行にまとめられる.

```rb
age = 18
puts age >= 20 ? "Adult" : "Minor"
```

上記の例ではage >= 20がtrueなら"Adult", falseなら"Minor"を出力する. ただし, この三項演算子を多用しすぎるとコードが読みにくくなる場合があるので, 適度に活用することが望ましい.

### if修飾子とunless修飾子
1行でシンプルな判定と処理を行うための構文としてif修飾子やunless修飾子がある. 後置if/後置unlessとも呼ばれ, 以下のように書ける.

```rb
score = 100
puts "Perfect!" if score == 100

is_debug_mode = false
puts "Debug mode is ON" unless is_debug_mode
```

if修飾子の場合は"if 条件"を行末に置き, unless修飾子の場合は"unless 条件"を行末に置く. 複雑な処理には向かないが, 単純な判定と1行出力が同時に必要なときは可読性が向上する.

## 繰り返し処理(while文, until文, for文, eachイテレータなど)

Rubyには複数の繰り返し方法があり, コードの意図に合わせて使い分けられる. さらにbreak, next, redoなどの制御構文を組み合わせることで, 柔軟なループ処理を記述できる.

### while 
条件が真の間ループを継続する. 条件が最初にチェックされるので, 必要に応じて条件変数を更新しないと無限ループが発生する可能性がある.

```rb
count = 0
while count < 5
  puts count
  count += 1
end
```
上記ではcountが5未満の間, ループが繰り返される. 毎回countをインクリメントしていき, countが5になった時点でループを抜ける.

### until  
条件が偽の間ループを継続する構文である. 直感的にはwhile文の逆バージョンであり, do...while構文のように使われることが多い.

```rb
count = 5
until count == 0
  puts count
  count -= 1
end
```
countが0になるまで, つまりcount == 0がtrueになるまでループを実行し続ける. したがって5,4,3,2,1と出力され, countが0になるとループを抜ける.

### for
C言語などに近い構文だが, Rubyでは内部的にeachを呼び出している. 通常は配列や範囲オブジェクト(1..3など)を指定し, 要素を順に取り出す.

```rb
for i in 1..3
  puts i
end
```
1,2,3と順に出力される. Rubyの慣習としてはfor文よりeachイテレータを多用する場合が多い.

### eachイテレータ
ブロックを用いて配列などの要素を順に処理する. breakやnextなどを組み合わせると, ループを細かく制御できる.

```rb
[1,2,3,4,5].each do |n|
  break if n > 3
  next if n == 2
  puts n
end
```

この例ではnが2のときはnextでスキップし, nが4を超えたときはbreakでループを終了する. 結果的に1と3のみが出力される.

### loop do文
Ruby独自のloop do ... end構文を使えば, 条件判定を任意のタイミングで行いつつ永遠に繰り返すループを記述できる.

```rb
count = 0
loop do
  count += 1
  puts "Looping... #{count}"
  break if count >= 3
end
```
ここではbreakが呼ばれるまで繰り返しが続き, countが3になった時点でループが抜けられる.

### 制御構文: break, next, redoなど
Rubyの繰り返し処理には, breakやnext, redoなどの制御構文が用意されている. それぞれの挙動を理解して使い分けることで, より柔軟なループ処理を実現できる. また, Ruby 2.0まではretryも存在したが, 現在は非推奨である.

#### break
ループ全体を抜ける. 例えば, iが5になったらループを終了したい場合に使う.

```rb
10.times do |i|
  if i == 5
    break
  end
  puts i
end
# => 0,1,2,3,4 で終了
```
#### next
現在の繰り返しだけをスキップし, 次の繰り返しへ移る. 例えば, iが2のときだけ出力を飛ばす.

```rb
10.times do |i|
  if i == 2
    next
  end
  puts i
end
# => 0,1,(2はスキップ),3,4,5,6,7,8,9
```
### redo
今の繰り返しを最初からやり直す. ただし条件式は再評価されないため, 使い方を誤ると無限ループに陥りやすい.

```rb
count = 0
5.times do |i|
  if i == 2 && count < 2
    count += 1
    puts "Redo at i=#{i}, count=#{count}"
    redo  # iの値を変えないままループをやり直す
  end
  puts i
end

# この例では, i=2に初めて到達したときredoを実行し,
# 再びi=2の処理が行われる(countが増加).
# countが2になるまでredoが繰り返される.
# 出力イメージ:
# 0
# 1
# Redo at i=2, count=1
# Redo at i=2, count=2
# 2
# 3
# 4
```

この例では, 0,1の後に2でスキップして, 3,4と出力, 5でbreakして終了する. したがって結果的に0,1,3,4が出力される.

## メソッド
### 1. メソッドの基本定義
Rubyにおいてメソッドは`def`キーワードで定義し, `end`で終了する. クラスやモジュールの外側に定義したメソッドは「トップレベルメソッド」と呼ばれ, そのまま呼び出すことができる. (実際にはObjectクラスの特異メソッドとして定義される)

```rb
def say_hello
  puts "Hello, world!"
end

say_hello  # => "Hello, world!"
```
- メソッド名は小文字またはアンダースコアで始めるのが一般的.
- `def say_hello; ... ; end`のように1行で定義することも可能.

### 2. 引数の渡し方
#### (1) 通常の引数
複数の引数はカンマで区切る. 必要に応じてデフォルト値を設定したり, キーワード引数を使ったりできる.

```rb
def greet(name, language)
  puts "Hello, #{name}. Programming language is #{language}."
end

greet("Alice", "Ruby")
# => "Hello, Alice. Programming language is Ruby."
```
#### (2) デフォルト引数
引数にデフォルト値を与えると, 呼び出し時に対応する引数を省略可能になる.

```rb
def greet(name = "Guest", language = "Ruby")
  puts "Hello, #{name}. Language is #{language}."
end

greet
# => "Hello, Guest. Language is Ruby."
greet("Bob")
# => "Hello, Bob. Language is Ruby."
greet("Carol", "Python")
# => "Hello, Carol. Language is Python."
```
#### (3) キーワード引数
Ruby 2.0以降で導入された機能で, 引数を「キー: 値」の形式で受け取る. 順番に依存せずに渡せる利点がある. デフォルト値の指定も可能.

```rb
def user_info(name:, age:, country: "Japan")
  puts "Name: #{name}, Age: #{age}, Country: #{country}"
end

user_info(name: "Dave", age: 32)
# => "Name: Dave, Age: 32, Country: Japan"
user_info(age: 25, name: "Erica", country: "USA")
# => "Name: Erica, Age: 25, Country: USA"
```
#### (4) 可変長引数(スプラット引数)
引数の数が不定の場合に, `*args`として受け取ることができる. また, キーワード引数を不定個受け取る`**opts`もある.

```rb
def sum_numbers(*nums)
  nums.sum
end

puts sum_numbers(1,2,3,4,5)  # => 15
puts sum_numbers(10, 20)     # => 30

def show_options(**opts)
  puts opts.inspect
end

show_options(color: "red", size: 10)
# => {:color=>"red", :size=>10}
```
### 3. 戻り値について
Rubyでは、メソッドの最後に評価された式がそのメソッドの戻り値となる. `return`を省略することが多いが, 必要に応じて任意の箇所で`return`を使って明示的に値を返すこともできる.

```rb
def add(a, b)
  a + b  # これが最後に評価されるので戻り値となる
end

puts add(2,3)  # => 5

def subtract(a, b)
  return a - b
end

puts subtract(5,2)  # => 3
```
### 4. メソッド呼び出し時のカッコの省略
Rubyでは, 引数が一つの場合や, 文脈が明らかな場合はメソッド呼び出しの丸括弧()を省略できる. ただし, メソッドチェーンの可読性や引数の明示性を考慮して, チームごとのコーディング規約に合わせることが多い.

```rb
def greet(name)
  "Hello, #{name}"
end

puts greet "Alice"   # => "Hello, Alice"
# 書き方によっては曖昧になる場合があるので注意.
```
### 5. ブロック・yield・高階メソッドとの関係
Rubyでは「関数(メソッド)」に対してブロックを渡すことができる. このブロックはメソッド内で`yield`を呼び出すことで実行される. Rubyのイテレータ(each, mapなど)はこれを活用している.

```rb
def with_logging
  puts "Start"
  yield if block_given?  # ブロックが渡されていれば実行
  puts "End"
end

with_logging do
  puts "Processing..."
end
# =>
# Start
# Processing...
# End
```
- `block_given?`はメソッドにブロックが渡されているかを判定するメソッド.
- ブロックを引数として受け取りたい場合は, 引数リストの最後に`&block`を指定する. するとブロックは`Proc`オブジェクトとして扱える.

```rb
def with_block(&block)
  puts "Before block"
  block.call
  puts "After block"
end

with_block do
  puts "Inside block"
end
# =>
# Before block
# Inside block
# After block
```
### 6. Proc・Lambda・メソッドオブジェクト
#### (1) Proc
Rubyではブロックをオブジェクト化した`Proc`クラスがあり, 関数ポインタのように扱える. `Proc.new`で生成, あるいは`proc { ... }`の糖衣構文で作成できる.

```rb
double_proc = Proc.new { |x| x * 2 }
puts double_proc.call(10)  # => 20
```
#### (2) lambda
`->(引数){ 処理 }`や`lambda`キーワードで作成する. Procとの違いは, 引数のチェックの厳しさ, returnの振る舞い, selfの扱いなどが挙げられる. 一般にlambdaのほうが「メソッドライクな挙動」をする.

```rb
triple_lambda = ->(x){ x * 3 }
puts triple_lambda.call(5)  # => 15
```
#### (3) メソッドオブジェクト
既存のメソッドをオブジェクトとして扱うには, `method(:メソッド名)`を用いる. コールするときは`.call`を使う.

```rb
def hello(name)
  "Hello, #{name}"
end

hello_method = method(:hello)
puts hello_method.call("Ruby")  # => "Hello, Ruby"
```
### 7. 特殊なメソッド(クラスメソッド・特異メソッド)
#### (1) クラスメソッド
クラス内部で`def self.method_name`と定義すると, クラスに紐づくメソッドとして呼び出せる.
後ほどオブジェクト指向プログラミングのセクションで説明する．

```rb
class MathUtil
  def self.add(a, b)
    a + b
  end
end

puts MathUtil.add(2,3)  # => 5
```
#### (2) 特異メソッド(オブジェクトのみに定義されたメソッド)
特定のインスタンスにだけメソッドを追加したい場合, `class << obj`や`def obj.method_name`で定義できる. メタプログラミングでよく使われる手法.

```rb
str = "Hello"
def str.shout
  upcase + "!!!"
end

puts str.shout  # => "HELLO!!!"
# 他の文字列にはこのメソッドはない
```
### 8. メソッドのエイリアスと再定義
Rubyでは`alias`キーワードを使うと, 同じ実体を持つメソッドに別名を与えられる. 既存クラスや自作クラスのメソッドを再定義(オープンクラス)できる点もRubyの特徴である. ただし, 他人が作ったライブラリのメソッドを安易に再定義するのは衝突や混乱の元となるため注意が必要.

```rb
class String
  alias :old_size :size

  def size
    puts "Calling my custom size method!"
    old_size
  end
end

str = "Hello"
puts str.size
# => "Calling my custom size method!"
# => 5
```

## オブジェクト指向プログラミング(OOP)

Rubyはすべてがオブジェクトであり, OOPを自然に扱うための機能が豊富に用意されている. OOPとは, データ(インスタンス変数)と振る舞い(メソッド)をひとまとまりのクラス(オブジェクトの設計図)にまとめる設計思想である. これにより, コードの再利用性が高まり, メンテナンスしやすいプログラムを書くことができる.

オブジェクト指向についてはこの記事で(TypeScriptで書いてます...)

https://qiita.com/JavaLangRuntimeException/items/cadf49bb419076819963

### クラスの定義
クラスはclassキーワードで始め, endで終了する. Rubyにおけるコンストラクタはinitializeメソッドで実装し, インスタンス生成時に呼び出される. また, attr_accessor, attr_reader, attr_writerを使うことで, インスタンス変数のアクセサメソッドを自動で定義できる.

```rb
class Person
  attr_accessor :name, :age
  
  def initialize(name, age)
    @name = name
    @age = age
  end
  
  def greet
    "Hello, I am #{@name}, and I am #{@age} years old."
  end
end

alice = Person.new("Alice", 20)
puts alice.greet
alice.name = "Alicia"
puts alice.greet
```
上記ではattr_accessor :name, :ageを宣言しているため, alice.nameやalice.ageを直接参照したり, 再代入したりできる(getter, setterが自動生成される).

### インスタンス変数とローカル変数
クラス内で@から始まる変数はインスタンス変数と呼ばれ, そのインスタンス専用のデータ領域として保持される. 一方, 単に小文字で始まる変数はローカル変数であり, メソッド内やブロック内でのみ有効である.

```rb
class Example
  def initialize
    @instance_var = "I'm an instance variable"
    local_var = "I'm a local variable"
  end

  def show_variables
    puts @instance_var
    # puts local_var  # これはエラーとなる(メソッドが異なるのでlocal_varが参照できない)
  end
end

obj = Example.new
obj.show_variables
```
### アクセス修飾子
Rubyではpublic, protected, privateの3種類のアクセス修飾子がある. デフォルトはpublicだが, コードの可読性を高めるために, メソッド定義の前にprivateなどを置いて以降のメソッドを非公開にする, というようにまとめて指定することが多い.

```rb
class Secret
  def public_info
    "This info is public."
  end

  private
  
  def secret_info
    "This info is hidden."
  end
end

obj = Secret.new
puts obj.public_info    # => "This info is public."
# puts obj.secret_info   # => NoMethodError (private method呼び出しのため)
```
protectedは同じクラス, もしくはサブクラスのインスタンス同士からのみ呼び出せるときに使う. 実際にはpublicかprivateを使うことが多い.

### 継承とメソッドのオーバーライド
クラスの名前の後に<をつけ, その後に親クラスを指定することで継承関係を定義できる. サブクラスでは同名のメソッドを再定義(オーバーライド)することで, 親クラスの振る舞いを上書きできる. superキーワードを使って親クラスのメソッドを呼び出すこともできる.

```rb
class Animal
  def speak
    "..."
  end
end

class Dog < Animal
  def speak
    "Woof!"
  end
end

dog = Dog.new
puts dog.speak  # => "Woof!"

# 親クラスのメソッドを呼びたい場合
class LoudDog < Dog
  def speak
    original = super  # 親クラス(Dog)のspeakを呼び出す
    "#{original} #{original}".upcase
  end
end

loud_dog = LoudDog.new
puts loud_dog.speak  # => "WOOF! WOOF!"
```
### クラス変数とクラスメソッド
クラス全体で共有する変数を@@varのようなクラス変数として定義できる. また, クラスメソッドを定義するときはdef self.method_nameのように書くか, class << selfブロック内で定義する. ただし, クラス変数の使用は多人数開発では混乱を招きやすいとして推奨されない場合もあるため, 代わりにクラスインスタンス変数(@var)やシングルトンメソッドを使う場合が多い.

```rb
class Counter
  @@count = 0
  
  def initialize
    @@count += 1
  end

  def self.total
    @@count
  end
end

obj1 = Counter.new
obj2 = Counter.new
puts Counter.total  # => 2
```
### 抽象クラス
Rubyには言語仕様として抽象クラスという概念が存在しない. しかし, インスタンスを作ってほしくないクラスや, そのままでは動かない(サブクラスで実装してほしい)メソッドを含むクラスを作成したい場合は, コンストラクタでエラーを投げるなどの対応を行うことがある. また, moduleを使ってインターフェイス的に振る舞いを強制するデザインも可能である.

```rb
class AbstractAnimal
  def initialize
    if self.class == AbstractAnimal
      raise "Cannot instantiate abstract class"
    end
  end
  
  def speak
    raise "Must implement speak in subclass"
  end
end

class Cat < AbstractAnimal
  def speak
    "Meow!"
  end
end

# 以下はエラーとなる
# abstract_animal = AbstractAnimal.new

cat = Cat.new
puts cat.speak  # => "Meow!"
```
### モジュール(Mixin)による多重継承の回避
Rubyは単一継承であり, 複数の親クラスを継承することはできない. 代わりにモジュールをincludeまたはextendすることで, クラスの機能を拡張するMixinが可能となっている.

```rb
module Loggable
  def log(message)
    puts "[LOG] #{message}"
  end
end

class Machine
  include Loggable
  
  def start
    log("Machine is starting...")
  end
end

machine = Machine.new
machine.start  # => [LOG] Machine is starting...
```

このように, Rubyのオブジェクト指向はシンプルな文法ながら強力で, 小規模から大規模開発まで幅広く対応できる. OOPの概念に慣れ親しんでいない場合でも, Rubyで学びやすい設計となっている.

# Ruby on Railsチートシート

Ruby on Rails(以下Rails)はRuby言語で書かれたWebアプリケーションフレームワークである. 「プログラマの幸福」を重視するRubyの思想を色濃く受け継ぎ, “Convention over Configuration”(設定より規約)と “DRY”(Don’t Repeat Yourself) を理念として掲げている. Railsのコードを見れば分かるとおり, 開発者が最低限の設定を記述するだけで多くの作業が自動化され, 高い生産性を実現できる.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/e675b923-6a86-d508-b852-f53024427520.png)


## Railsの概念と歴史
Railsは2004年にDavid Heinemeier Hansson(DHH)によって開発が開始され, 2005年に正式にリリースされた. 当時, Ruby自体は日本国内ではある程度知られていたが, 国際的には今ほど普及していなかった. Railsの登場により, Rubyとセットで爆発的に広まり, Webアプリケーションフレームワークの代表格となった. Railsは“Convention over Configuration”を強く打ち出し, コードの記述量を大幅に削減できる点が注目を集めた. また, Active Recordパターンによる強力なORマッパーが標準搭載され, MVC(Model-View-Controller)アーキテクチャをベースにすることで, 分かりやすい構造のWebアプリケーションを作成しやすくなっている.

## 採用されているアーキテクチャ(MVC)
RailsはMVC(Model-View-Controller)をアプリケーション構造の中心に据えている.
**1. Model**
アプリケーションのビジネスロジックやデータベースとのやり取りを担う. RailsではActive Recordライブラリを通してテーブルとモデルが1対1で対応し, クエリをほぼ意識せずにデータ操作できる.
**2. View**
ユーザーが直接目にする部分で, HTMLやCSS, JavaScriptで構成される. RailsではERBやHaml, Slimなどのテンプレートエンジンが利用できる.
**3. Controller**
ModelとViewを仲介する役割を持つ. ルーティングから受け取ったリクエストを処理し, 必要なデータをModelに問い合わせ, レスポンスとしてViewに描画させる.

これらの役割が明確に分離されているため, コードの見通しが良く, 変更にも強いアプリケーションを開発できる.

:::note info
**MVCアーキテクチャの利点と他のアーキテクチャとの比較**
**1.MVCの主な利点**
- モデル・ビュー・コントローラーの役割が明確に分かれており, コードの見通しが良い.
- ビジネスロジック(Model)とプレゼンテーション(View)が分離されているため, UIの変更が容易である.
- テストが書きやすく, ユニットテストの実施が容易である.
- 大規模なアプリケーション開発に適している.

**2. 他のアーキテクチャとの比較**

**MVP (Model-View-Presenter)**
- ViewとModelの依存関係が完全に分離されている.
- PresenterがViewとModelの橋渡しをする.
- MVCよりもView層のテストが容易である.
- コード量が多くなりがちである.

**MVVM (Model-View-ViewModel)**
- データバインディングを活用する.
- ViewとViewModelの関係が密接である.
- 主にクライアントサイドのアプリケーションで使用される.
- UIの状態管理が容易である.

**Clean Architecture**
- よりレイヤー化が進んだアーキテクチャである.
- 依存関係が内側に向かうように制御される.
- MVCよりも複雑だが, より厳密な責務の分離が可能である.
- 大規模システムに向いている.
:::

## どんなプロジェクトが向いているか
Railsは以下のようなプロジェクトで特に力を発揮する.
**1. スタートアップやプロトタイプ作成**
Scaffold(足場生成)などの機能により, とにかく素早く動くアプリを作りたいときに有利である.
**2. 中規模から大規模のWebサービス**
データベースを多用するサービスやECサイトなど, 多機能なWebアプリケーションを短期間で構築できる.
**3. コミュニティやSNS, 予約システムなど**
ユーザーアカウント管理や各種のRDB操作がセットになったWebアプリ全般に向いている.

一方で, 大量の同時接続が要求されるリアルタイム性が非常に高いサービス(ゲームサーバや超高トラフィックのチャットなど)には, イベント駆動や並行処理が得意な他の技術を組み合わせることが多い. もちろんRailsもマルチプロセスやスレッドを扱うが, GoやElixirなどの並行処理が得意な言語ほど特化はしていない.

## GoやPythonとの違い
- **Go** 
静的型付け言語であり, 並列・並行処理が得意. 一方でWebフレームワークは多数あるがRailsほど「すぐに開発できる」統合的な仕組みが整備されているわけではない. 設定を明示的に行うことが多く, “Convention over Configuration”というRailsのような思想とは逆の方向性といえる.  
- **Python** 
動的型付けであり, DjangoやFlaskなどフレームワークは豊富. Webアプリだけでなく機械学習やデータサイエンスの分野でも強みを持つ. Railsに比べると「標準で全て揃う」というよりは, 組み合わせて自分に合ったスタックを作る印象が強い.

Railsは「とにかくWebアプリを素早く構築したい」「統合的なフレームワークを使いたい」場合に適しており, GoやPythonに比べるとプロトタイプを高速に開発できるメリットがある. しかし, 並行処理や軽量性の面ではGoの方が優れている, ML分野ではPythonが優れている, といった住み分けが存在する.

## Railsの開発手法
Railsを使ったアプリケーション開発は, 「rails newコマンドでプロジェクトを作るところから始まり, モデルやコントローラを生成して機能を実装し, データベースをマイグレーションで管理しながら全体を仕上げる」という流れが基本となる. 主な手順を以下に挙げる.

**1. Railsのインストールとプロジェクト作成** 
システムにRubyがインストールされていることを前提に, gemコマンドでRailsを導入する. その後, rails new コマンドで新規アプリケーションを生成する.  
```bash
gem install rails  
rails new myapp  
cd myapp
```
**2. MVCファイルの構成**
生成したプロジェクトには, app/models, app/views, app/controllersというディレクトリが用意され, それぞれに対応するコードを置く. ルーティングはconfig/routes.rbで定義する.  
```config/routes.rb
Rails.application.routes.draw do
 resources :users
end
```
**3. モデルの作成とマイグレーション**
rails generate model コマンドでモデルとマイグレーションファイル(データベースのスキーマを更新するためのファイル)を作成できる.  
```bash
rails generate model User name:string email:string  
rails db:migrate  
```
これによりusersテーブルが作成され, Userモデルがapp/models/user.rbに生成される. Active Record経由でデータベース操作を行うため, SQLを書く必要が最小限で済む.

**4. コントローラとアクションの定義** 
コントローラはrails generate controller コマンドで生成できる. ルーティング設定と組み合わせることで, URLやHTTPメソッドに応じてコントローラのアクションが呼び出される.  
```bash
rails generate controller Users index show new create edit update destroy
```
これによりapp/controllers/users_controller.rbが生成され, その中でindex, show, newなどのアクションを定義できる. これらのアクションがViewと組み合わさって画面を描画したり, データベースを操作したりする.

**5. Viewとテンプレートエンジン**
Viewはapp/views以下にコントローラ名のディレクトリを作り, その中にアクション名と対応するHTMLテンプレート(erb, haml, slimなど)を配置する.  
```erb
<!-- app/views/users/index.html.erb -->
<h1>User List</h1>
<ul>
<% @users.each do |user| %>
 <li><%= user.name %> (<%= user.email %>)</li>
<% end %>
</ul>
```
**6. Scaffoldによる自動生成**  
rails generate scaffold モデル名 ... コマンドを使うと, モデル, コントローラ, ビュー, ルート設定などが一度に生成される. プロトタイプ作成の段階で素早くCRUD機能を実装したい場合に便利である.  
```bash
rails generate scaffold Post title:string content:text  
rails db:migrate
```
これだけで投稿フォームや一覧, 詳細表示などが揃った簡易的なブログを作ることができる.

**7. アセットパイプラインとフロントエンド** 
Railsにはアセットパイプラインという仕組みがあり, CSSやJavaScriptを効率的に管理, コンパイルできる. WebpackerやWebpackでモダンなフロントエンドツールとも連携し, ReactやVue.jsなどを組み込み可能.

**8. テスト駆動開発(TDD)とRSpec**  
   RailsではMinitestが標準で付属しているが, RSpecを使うプロジェクトも多い. Railsアプリの各レイヤ(Model, Controller, Featureなど)に対してテストを書き, バグを早期発見しやすくする.  
```rb
RSpec.describe User, type: :model do
 it "is invalid without a name" do
   user = User.new(name: nil)
   expect(user).not_to be_valid
 end
end
```
**9. デプロイと運用**
   Railsアプリを本番運用する場合, CapistranoやDocker, あるいはHerokuなどを使い, サーバへデプロイを行う. PumaやPassengerなどのアプリケーションサーバとNginxなどを組み合わせ, スケールに応じて設定を調整する.


Railsは, 「規約に従う」ことで開発者が必要最低限のことだけ記述すれば, Webアプリの基本的な機能やディレクトリ構造, ルーティングなどが自動的に整備される. これによりスタートアップや中規模から大規模のサービス開発まで対応可能であり, “開発の速さ”と“保守のしやすさ”のバランスが良い. 一方で, GoやPythonとは得意分野が異なり, 並列・並行処理や科学技術計算など別の分野では他の言語が適している場合もある. Railsを選択するメリットとしては, ユーザー認証やCRUD, テンプレートエンジンなどWebアプリに必要な機能がほぼ一式そろっているため, 立ち上げが非常に速い点が挙げられる. また, 大規模なエコシステムとコミュニティによってドキュメントや情報が豊富に存在しており, 開発者にとって学習やトラブルシューティングがしやすい.

## Railsで簡単なUserモデルのAPIを作成する例
以下ではRailsのAPIモードを想定し, ユーザ情報(Userモデル)のCRUDを実装する最低限のソースコードを示す. Railsのバージョンは7.xを想定し, データベースはSQLite3を利用する. コマンドライン操作やファイル構成はローカル開発環境を前提とする.

**① プロジェクトの作成**
RailsのAPIモードを使う場合, --api オプションを付けてrails newコマンドを実行する.

```bash
rails new sample_api --api
cd sample_api
```
Gemfileなどは自動生成されるが, 今回はデフォルト構成のまま進める.

**② データベース設定**
デフォルトでSQLite3になっているため, そのまま利用する. config/database.ymlで接続設定が完了しているかを確認する(デフォルトのままでもOK).

**③ モデルとマイグレーションの作成**
ユーザの基本情報(name, email)を保持するUserモデルを作成する.

```bash
rails generate model User name:string email:string
```
上記コマンドで以下のようなファイルが生成される.

(日時部分は環境で異なる)
```db/migrate/20241225000000_create_users.rb 
class CreateUsers < ActiveRecord::Migration[7.0]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email

      t.timestamps
    end
  end
end
```
```app/models/user.rb
class User < ApplicationRecord
  validates :name, presence: true
  validates :email, presence: true
end
```
**④ マイグレーションの実行**
DBにテーブルを作成する.

```bash
rails db:migrate
```
**⑤ ルーティングの設定**
APIとしてユーザデータを操作するエンドポイントを用意する. config/routes.rbを編集し, resources :usersを追記する.

```config/routes.rb:
Rails.application.routes.draw do
  resources :users
end
```
これにより, /users へのGET/POST, /users/:id へのGET/PUT/PATCH/DELETEなどのルートが自動的に定義される.

**⑥ コントローラの作成**
rails generate controllerコマンドを使ってユーザ用コントローラを作成する. ただし, APIモードの場合はHTMLビューが不要なので, --no-assets --no-helperなどのオプションをつけるとよい. ここではシンプルに書く.

```bash
rails generate controller Users
```
app/controllers/users_controller.rb が作成されるので編集する. APIとしてJSONを返すことが前提のため, 各アクション内でrender json: ...の形式を用いる.

```app/controllers/users_controller.rb:
class UsersController < ApplicationController
  # Rails 7のAPIモードではCSRF保護がデフォルトで無効になっているが,
  # 通常のRailsモードであれば skip_before_action :verify_authenticity_token
  # のように書く場合もある.
  
  # GET /users
  def index
    users = User.all
    render json: users
  end

  # GET /users/:id
  def show
    user = User.find(params[:id])
    render json: user
  rescue ActiveRecord::RecordNotFound
    render json: { error: "User not found" }, status: :not_found
  end

  # POST /users
  def create
    user = User.new(user_params)
    if user.save
      render json: user, status: :created
    else
      render json: { errors: user.errors.full_messages }, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /users/:id
  def update
    user = User.find(params[:id])
    if user.update(user_params)
      render json: user
    else
      render json: { errors: user.errors.full_messages }, status: :unprocessable_entity
    end
  rescue ActiveRecord::RecordNotFound
    render json: { error: "User not found" }, status: :not_found
  end

  # DELETE /users/:id
  def destroy
    user = User.find(params[:id])
    user.destroy
    render json: { message: "User deleted" }, status: :ok
  rescue ActiveRecord::RecordNotFound
    render json: { error: "User not found" }, status: :not_found
  end

  private

  def user_params
    params.require(:user).permit(:name, :email)
  end
end
```
**⑦ 動作確認**
```bash
rails s
```
上記のコマンドでサーバを起動し, curlやHTTPクライアントを使って各エンドポイントにアクセスする. 以下に簡単な例を示す.

**1) ユーザの一覧取得**
GETリクエスト:
```bash
curl http://localhost:3000/users
```
**2) ユーザの新規作成** 
POSTリクエスト:
```bash
curl -X POST -H "Content-Type: application/json" \
  -d '{"user":{"name":"Alice","email":"alice@example.com"}}' \
  http://localhost:3000/users
```
**3) ユーザ詳細の取得**
GETリクエスト:
```bash
curl http://localhost:3000/users/1
```
**4) ユーザ情報の更新**
PATCHリクエスト:
```bash
curl -X PATCH -H "Content-Type: application/json" \
  -d '{"user":{"name":"Alicia"}}' \
  http://localhost:3000/users/1
```
**5) ユーザの削除** 
DELETEリクエスト:
```bash
curl -X DELETE http://localhost:3000/users/1
```
**⑧ 全体ファイル構成(抜粋)**
以下, rails new sample_api --api で作成した後に今回編集・追加した主なファイルを示す.
```
sample_api/
  app/
    controllers/
      application_controller.rb  # Rails APIモードで生成される
      users_controller.rb        # 追加
    models/
      user.rb                    # 追加
  config/
    routes.rb                   # 追記
  db/
    migrate/
      20241225000000_create_users.rb  # 生成されるマイグレーションファイル
  Gemfile
  Rakefile
  ...
```

これで簡単なUserモデルを用いたAPIサーバが完成する. 開発の要件に応じてバリデーションを追加したり, 認証・認可の仕組み(DeviseやJWTなど)を組み込んだり, テストフレームワーク(RSpecなど)で自動テストを書いたりしながら拡張していく.

# railsのディレクトリ構造
Railsアプリケーションは多数のファイルとディレクトリが生成され, それぞれが明確な役割を担っている. 以下では, 質問中に示されているディレクトリ構造をベースに, 主なフォルダやファイルについて説明する.

```
❯ tree
.
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── README.md
├── Rakefile
├── app
│   ├── channels
│   │   └── application_cable
│   │       ├── channel.rb
│   │       └── connection.rb
│   ├── controllers
│   │   ├── application_controller.rb
│   │   ├── concerns
│   │   └── users_controller.rb
│   ├── jobs
│   │   └── application_job.rb
│   ├── mailers
│   │   └── application_mailer.rb
│   ├── models
│   │   ├── application_record.rb
│   │   ├── concerns
│   │   └── user.rb
│   └── views
│       └── layouts
│           ├── mailer.html.erb
│           └── mailer.text.erb
├── bin
│   ├── bundle
│   ├── docker-entrypoint
│   ├── rails
│   ├── rake
│   └── setup
├── config
│   ├── application.rb
│   ├── boot.rb
│   ├── cable.yml
│   ├── credentials.yml.enc
│   ├── database.yml
│   ├── environment.rb
│   ├── environments
│   │   ├── development.rb
│   │   ├── production.rb
│   │   └── test.rb
│   ├── initializers
│   │   ├── cors.rb
│   │   ├── filter_parameter_logging.rb
│   │   └── inflections.rb
│   ├── locales
│   │   └── en.yml
│   ├── master.key
│   ├── puma.rb
│   ├── routes.rb
│   └── storage.yml
├── config.ru
├── db
│   ├── migrate
│   │   └── 20241225032929_create_users.rb
│   ├── schema.rb
│   └── seeds.rb
├── lib
│   └── tasks
├── log
│   └── development.log
├── public
│   └── robots.txt
├── storage
│   ├── development.sqlite3
│   ├── development.sqlite3-shm
│   └── development.sqlite3-wal
├── test
│   ├── channels
│   │   └── application_cable
│   │       └── connection_test.rb
│   ├── controllers
│   │   └── users_controller_test.rb
│   ├── fixtures
│   │   ├── files
│   │   └── users.yml
│   ├── integration
│   ├── mailers
│   ├── models
│   │   └── user_test.rb
│   └── test_helper.rb
```

- **1. ルートディレクトリ直下**
    - **Dockerfile**: DockerコンテナでRailsアプリケーションを動かすための設定ファイル. 使用するRubyのバージョンやパッケージのインストール手順などを記述する.
    - **Gemfile / Gemfile.lock**: Railsやその他のRubyライブラリ(gem)の依存関係を管理する. Gemfileに必要なgemを記述し, bundle installするとGemfile.lockが更新される.
    - **README.md**: プロジェクトの説明やセットアップ方法, 使用方法などをドキュメントとしてまとめておくためのファイル.
    - **Rakefile**: rakeコマンドで実行できるタスクを定義する. Railsだとデフォルトで多くのタスクが読み込まれる仕組みになっている.
    - **config.ru**: Rack用の設定ファイル. RailsアプリケーションをRackサーバ(例: Puma, Passengerなど)で動かす際に利用される.

- **2. appディレクトリ**
RailsのMVC構造の主要なコードが格納される. この下にモデルやコントローラ, ビューが配置される.

    - **app/channels**: Action Cable(リアルタイム機能)のチャンネル関連ファイルを置く.  
      - **application_cable**内には, channel.rbやconnection.rbがある.  
        - **channel.rb**: Action Cableで使用するチャンネルの共通機能.  
        - **connection.rb**: WebSocket接続における認証や接続時の処理を定義する.
    
    - **app/controllers**: コントローラを置くディレクトリ.  
      - **application_controller.rb**: 全コントローラの親クラスとなるコントローラ. ここで共通処理やフィルタを定義することが多い. **(Rails APIモードで生成される)**
      - **users_controller.rb**: ユーザ管理用のコントローラ．**(先ほど追加したもの)**
      - **concerns**: コントローラに共通するモジュールやMixin用ファイルを置くフォルダ(オプション).
    
    - **app/jobs**: 非同期ジョブ(Active Job)を定義する.  
      - **application_job.rb**: 全ジョブの親クラスとなるファイル.
    
    - **app/mailers**: メール送信機能を担うMailerクラスを置く.  
      - **application_mailer.rb**: 全Mailerの共通クラスとなるファイル.
    
    - **app/models**: モデルを配置するディレクトリ. DBテーブルとの対応やビジネスロジックを扱う.  
      - **application_record.rb**: Rails 5以降, 全モデルの継承元となる抽象クラス.  
      - **user.rb**: ユーザ関連のロジックやDBテーブル(usersテーブル)との関連を定義.  **(先ほど追加したもの)**
      - **concerns**: モデルに共通するモジュールやMixin用ファイルを置くフォルダ(オプション).
    
    - **app/views**: ビューテンプレート(HTML, ERBなど)を配置する.  
      - **layouts**: レイアウトファイルを置き, 各ページの共通部分(ヘッダ, フッタ)を定義する.  
        - **mailer.html.erb / mailer.text.erb**: メール送信時に使われるHTML形式/テキスト形式のレイアウトテンプレート.

- **3. binディレクトリ**
    - **rails, rake, bundle**などの実行用スクリプトが含まれる.  
    - **docker-entrypoint, setup**など, プロジェクト独自のスクリプトを置く場合もある.

- **4. configディレクトリ**
Railsアプリケーション全体の設定関連ファイルが入る.

    - **application.rb**: Railsアプリ全体の設定を行うファイル. ミドルウェアやautoloadの設定などを記述する.  
    - **boot.rb**: Railsを起動する際に必要な初期化処理を行う.  
    - **cable.yml**: Action Cableの設定ファイル.  
    - **credentials.yml.enc / master.key**: Railsの認証情報やAPIキーなどを暗号化して管理するためのファイル. master.keyで復号できる.  
    - **database.yml**: データベースの接続情報(開発, テスト, 本番環境など)を設定する.  
    - **environment.rb**: Railsの初期化プロセスを実行し, config/application.rbを読み込んで起動準備を行う.  
    - **environments**: Railsの環境ごとの設定ファイル(development.rb, production.rb, test.rb). ログレベルやキャッシュ設定など.  
    - **initializers**: Rails起動時に読み込ませる設定ファイルの置き場所.  
      - **cors.rb**: Cross-Origin Resource Sharing(CORS)の設定.  
      - **filter_parameter_logging.rb**: ログに書きたくないパラメータをフィルタする設定.  
      - **inflections.rb**: 英単語の単数形/複数形の変換規則を追加変更するときに使う.  
    - **locales**: i18nによる国際化対応で使う翻訳ファイル(en.ymlなど).  
    - **puma.rb**: デフォルトのアプリケーションサーバPumaの設定ファイル.  
    - **routes.rb**: ルーティング(URIパターンとコントローラの対応)を定義するファイル.  
    - **storage.yml**: Active Storageの設定(ファイル保存先など).

- **5. config.ru**
RackサーバがRailsを起動するときに利用する設定. RailsアプリがRackアプリケーションとして起動されるために必要.

- **6. dbディレクトリ**
データベースやマイグレーション関連のファイル.

    - **migrate**: マイグレーションファイルを置くディレクトリ. DBのスキーマ変更を管理する.  
      - **20241225032929_create_users.rb**など, 日付入りのファイル名で作成される. **(先ほど追加したもの)** 
    - **schema.rb**: 現在のDBのスキーマ情報が記録される.  
    - **seeds.rb**: 初期データ投入(シードデータ)を定義するファイル.

- **7. libディレクトリ**
独自のモジュールやタスクなどを配置できる. Rails 6以降ではオートロードパスに含まれないことが多いので, 必要に応じて設定を行う.

    - **tasks**: Rakeタスク定義ファイル(*.rake)を置くディレクトリ.

- **8. logディレクトリ**
Railsが出力するログファイル(各環境ごとにdevelopment.log, production.log, test.logなど)が格納される.

- **9. publicディレクトリ**
静的ファイル(HTML, 画像, CSS, JavaScriptなど)を配置する. Railsで直接返せる.  
- **robots.txt**などがあり, クローラへの指示などを記述できる.

- **10. storageディレクトリ**
Active Storage(ファイルアップロード機能)が利用する実際のファイル保存先.  
    - SQLiteのDBファイルがここに置かれているケース(例としてdevelopment.sqlite3など)もあるが, 通常はdbディレクトリや別の場所に配置することが多い.

- **11. testディレクトリ**
Railsの標準テストフレームワーク(Minitest)用のファイルを配置する.  
    - **channels, controllers, models**など, アプリ構造に合わせてテストファイルを分割する.  
    - **fixtures**: テストデータを定義し, テストの実行前にDBへ投入する.  
    - **test_helper.rb**: テストを実行する際の共通設定やヘルパーメソッドを定義する.

全体の流れとしては, Railsのアプリケーションコード(モデル, コントローラ, ビュー)がappディレクトリに集約され, それらが設定ファイル(config以下)と連携しながら動作する. データベース関連はdb配下で管理し, テスト関連はtestにまとめる. binやlibなども補助的なスクリプトやライブラリを配置する場所として機能している.