Skip to content

Commit 4822427

Browse files
committed
7章まで
1 parent bb7f0d3 commit 4822427

File tree

6 files changed

+955
-186
lines changed

6 files changed

+955
-186
lines changed

app/pagesList.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ export const pagesList = [
2828
{ id: 1, title: "rubyの世界へようこそ" },
2929
{ id: 2, title: "基本構文とデータ型" },
3030
{ id: 3, title: "制御構造とメソッド定義" },
31-
{ id: 4, title: "ブロックとイテレータ" },
32-
{ id: 5, title: "すべてがオブジェクト" },
33-
{ id: 6, title: "コレクション (Array, Hash, Range)" },
31+
{ id: 4, title: "すべてがオブジェクト" },
32+
{ id: 5, title: "コレクション (Array, Hash, Range)" },
33+
{ id: 6, title: "ブロックとイテレータ" },
3434
{ id: 7, title: "クラスとオブジェクト" },
3535
{ id: 8, title: "モジュールとMix-in" },
3636
{ id: 9, title: "Proc, Lambda, クロージャ" },

app/terminal/runtime.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ export function langConstants(lang: RuntimeLang | AceLang): LangConstants {
102102
tabSize: 2,
103103
// TODO: 実際のirbのプロンプトは静的でなく、(main)や番号などの動的な表示がある
104104
prompt: "irb> ",
105+
promptMore: "irb* ",
105106
returnPrefix: "=> ",
106107
};
107108
case "javascript":

public/docs/ruby-4.md

Lines changed: 117 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -1,246 +1,180 @@
1-
# 第4章: ブロックとイテレータ - Rubyの最重要機能
1+
# 第4章: すべてがオブジェクト
22

3-
Rubyの学習において、**ブロック (Block)** は最も重要で強力な機能の一つです。他言語の経験者にとって、これはラムダ式や無名関数、クロージャに似た概念ですが、Rubyではこれが言語構文の核に深く組み込まれています
3+
Rubyの設計思想における最も重要かつ強力なコンセプトの一つは、「すべてがオブジェクトである」という点です。他の言語、例えばJavaやC++では、数値(int, double)や真偽値(boolean)は「プリミティブ型」として扱われ、オブジェクトとは区別されます
44

5-
この章では、ブロックの使い方と、ブロックを活用する「イテレータ」と呼ばれるメソッドを学びます
5+
しかしRubyでは、`5` のような数値も、`"hello"` のような文字列も、そして `nil` さえも、すべてがメソッド(振る舞い)を持つオブジェクトです
66

7-
## ブロック構文: do...end と {}
7+
## 🎯 Rubyの核心: 5.times の衝撃
88

9-
ブロックとは、メソッド呼び出しに渡すことができる**コードの塊**です。メソッド側は、受け取ったそのコードの塊を好きなタイミングで実行できます。
10-
11-
ブロックには2種類の書き方があります。
12-
13-
1. **`{ ... }` (波括弧)**: 通常、1行で完結する場合に使われます。
14-
2. **`do ... end`**: 複数行にわたる処理を書く場合に使われます。
15-
16-
どちらも機能的にはほぼ同じです。最も簡単な例は、指定した回数だけブロックを実行する `times` メソッドです。
9+
他の言語の経験者がRubyに触れて最初に驚くことの一つが、以下のようなコードが動作することです。
1710

1811
```ruby-repl:1
19-
irb(main):001:0> 3.times { puts "Hello!" }
20-
Hello!
21-
Hello!
22-
Hello!
23-
=> 3
24-
25-
irb(main):002:0> 3.times do
26-
irb(main):003:1* puts "Ruby is fun!"
27-
irb(main):004:1> end
28-
Ruby is fun!
29-
Ruby is fun!
30-
Ruby is fun!
31-
=> 3
12+
irb(main):001:0> 5.times do
13+
irb(main):002:1* print "Ruby! "
14+
irb(main):003:1> end
15+
Ruby! Ruby! Ruby! Ruby! Ruby! => 5
3216
```
3317

34-
`3.times` というメソッド呼び出しの後ろに `{ ... }``do ... end` で囲まれたコードブロックを渡しています。`times` メソッドは、そのブロックを3回実行します。
35-
36-
## 代表的なイテレータ
37-
38-
Rubyでは、コレクション(配列やハッシュなど)の各要素に対して処理を行うメソッドを**イテレータ (Iterator)** と呼びます。イテレータは通常、ブロックを受け取って動作します。
18+
`5` という数値リテラルが `.times` というメソッドを呼び出しています。これは、`5` が単なる値ではなく、`Integer` クラスのインスタンス(オブジェクト)だからです。
3919

40-
代表的なイテレータを見ていきましょう。
41-
42-
### each
43-
44-
`each` は、コレクションの各要素を順番に取り出してブロックを実行します。他言語の `foreach` ループに最も近いものです。
45-
46-
`|n|` の部分は**ブロック引数**と呼ばれ、イテレータが取り出した要素(この場合は配列の各要素)を受け取ります。
20+
同様に、文字列もオブジェクトです。
4721

4822
```ruby-repl:2
49-
irb(main):001:0> numbers = [1, 2, 3]
50-
=> [1, 2, 3]
51-
52-
irb(main):002:0> numbers.each do |n|
53-
irb(main):003:1* puts "Current number is #{n}"
54-
irb(main):004:1> end
55-
Current number is 1
56-
Current number is 2
57-
Current number is 3
58-
=> [1, 2, 3]
23+
irb(main):001:0> "hello, world".upcase
24+
=> "HELLO, WORLD"
25+
irb(main):002:0> "hello, world".length
26+
=> 12
5927
```
6028

61-
> **Note:** `each` メソッドの戻り値は、元の配列 (`[1, 2, 3]`) 自身です。`each` はあくまで「繰り返すこと」が目的であり、ブロックの実行結果は利用しません。
62-
63-
### map (collect)
29+
`"hello, world"` という `String` オブジェクトが、`upcase``length` というメソッド(メッセージ)に応答しています。
6430

65-
`map` は、各要素に対してブロックを実行し、その**ブロックの戻り値**を集めた**新しい配列**を返します
31+
`.class` メソッドを使うと、そのオブジェクトがどのクラスに属しているかを確認できます
6632

6733
```ruby-repl:3
68-
irb(main):005:0> numbers = [1, 2, 3]
69-
=> [1, 2, 3]
70-
71-
irb(main):006:0> doubled = numbers.map { |n| n * 2 }
72-
=> [2, 4, 6]
73-
74-
irb(main):007:0> puts doubled.inspect
75-
[2, 4, 6]
76-
=> nil
77-
78-
irb(main):008:0> puts numbers.inspect # 元の配列は変更されない
79-
[1, 2, 3]
80-
=> nil
34+
irb(main):001:0> 5.class
35+
=> Integer
36+
irb(main):002:0> "hello".class
37+
=> String
38+
irb(main):003:0> 3.14.class
39+
=> Float
8140
```
8241

83-
`map` は、元の配列を変換した新しい配列が欲しい場合に非常に便利です。
42+
## 👻 nil オブジェクト: 無ですらオブジェクト
8443

85-
### select (filter)
44+
Rubyには「何もない」「無効」な状態を示す `nil` という特別な値があります。これは他の言語における `null``None` に相当します。
8645

87-
`select` は、各要素に対してブロックを実行し、ブロックの戻り値が**真 (true)** になった要素だけを集めた**新しい配列**を返します
46+
しかし、Rubyの哲学を徹底している点は、この `nil` ですらオブジェクトであるということです
8847

8948
```ruby-repl:4
90-
irb(main):009:0> numbers = [1, 2, 3, 4, 5, 6]
91-
=> [1, 2, 3, 4, 5, 6]
92-
93-
irb(main):010:0> evens = numbers.select { |n| n.even? } # n.even? は n % 2 == 0 と同じ
94-
=> [2, 4, 6]
49+
irb(main):001:0> nil.class
50+
=> NilClass
9551
```
9652

97-
### find (detect)
98-
99-
`find` は、ブロックの戻り値が**真 (true)** になった**最初の要素**を返します。見つからなければ `nil` を返します。
53+
`nil``NilClass` という専用クラスの唯一のインスタンスです。オブジェクトであるため、`nil` もメソッドを持ちます。
10054

10155
```ruby-repl:5
102-
irb(main):011:0> numbers = [1, 2, 3, 4, 5, 6]
103-
=> [1, 2, 3, 4, 5, 6]
104-
105-
irb(main):012:0> first_even = numbers.find { |n| n.even? }
106-
=> 2
107-
108-
irb(main):013:0> over_10 = numbers.find { |n| n > 10 }
109-
=> nil
110-
```
111-
112-
## for ループとの比較
113-
114-
他言語経験者の方は、`for` ループを使いたくなるかもしれません。
115-
116-
```c
117-
// C や Java の for ループ
118-
for (int i = 0; i < 3; i++) {
119-
printf("Hello\n");
120-
}
56+
irb(main):001:0> nil.nil?
57+
=> true
58+
irb(main):002:0> "hello".nil?
59+
=> false
60+
irb(main):003:0> nil.to_s
61+
=> ""
62+
irb(main):004:0> nil.to_i
63+
=> 0
12164
```
12265

123-
Rubyにも `for` 構文は存在します
66+
`nil` がメソッドを持つことで、`null` チェックに起因するエラー(例えば `null.someMethod()` のような呼び出しによるエラー)を避けやすくなり、より安全で流暢なコードが書ける場合があります
12467

125-
```ruby-repl:6
126-
irb(main):014:0> numbers = [1, 2, 3]
127-
=> [1, 2, 3]
128-
129-
irb(main):015:0> for num in numbers
130-
irb(main):016:1* puts num
131-
irb(main):017:1> end
132-
1
133-
2
134-
3
135-
=> [1, 2, 3]
136-
```
68+
## 📨 メソッド呼び出しの仕組み: メッセージパッシング
13769

138-
しかし、Rubyの世界では `for` ループは**ほとんど使われません**。なぜなら、`for` は内部的に `each` メソッドを呼び出しているに過ぎないからです
70+
Rubyのメソッド呼び出し `オブジェクト.メソッド名(引数)` は、厳密には「**メッセージパッシング**」という概念に基づいています
13971

140-
Rubyプログラマは、`for` よりも `each` などのイテレータをブロックと共に使うことを圧倒的に好みます。イテレータの方が、何をしているか(単なる繰り返し、変換、選択など)がメソッド名 (`each`, `map`, `select`) から明確であり、コードが読みやすくなるためです
72+
`5.times` というコードは、以下のように解釈されます
14173

142-
## ブロック引数とブロックの戻り値
74+
1. レシーバ(受信者): `5` という `Integer` オブジェクト
75+
2. メッセージ: `:times` というシンボル(メソッド名)
76+
3. `5` オブジェクトに `:times` というメッセージを送る。
77+
4. `5` オブジェクト(の所属する `Integer` クラス)は、そのメッセージを解釈し、関連付けられた処理(ブロックを5回実行する)を実行する。
14378

144-
すでに出てきたように、ブロックは `| ... |` を使って引数を受け取ることができます
79+
この考え方は、オブジェクト指向の「カプセル化(オブジェクトが自身の振る舞いを決定する)」を強力にサポートします。`+` などの演算子でさえ、実際にはメソッド呼び出しのシンタックスシュガー(糖衣構文)です
14580

146-
```ruby-repl:7
147-
irb(main):018:0> ["Alice", "Bob"].each do |name|
148-
irb(main):019:1* puts "Hello, #{name}!"
149-
irb(main):020:1> end
150-
Hello, Alice!
151-
Hello, Bob!
152-
=> ["Alice", "Bob"]
81+
```ruby-repl:6
82+
irb(main):001:0> 10 + 3
83+
=> 13
84+
irb(main):002:0> 10.+(3) # 内部的にはこれと同じ
85+
=> 13
15386
```
15487

155-
また、ブロックも(Rubyのすべての式と同様に)戻り値を持ちます。ブロックの戻り値とは、**ブロック内で最後に評価された式の値**です。
156-
157-
* `each` はブロックの戻り値を**無視**します。
158-
* `map` はブロックの戻り値を**集めて新しい配列**にします。
159-
* `select` はブロックの戻り値が**真か偽か**を判定に使います。
160-
161-
```ruby-repl:8
162-
irb(main):021:0> result = [1, 2].map do |n|
163-
irb(main):022:1* m = n * 10 # mは 10, 20
164-
irb(main):023:1* m + 5 # ブロックの戻り値 (15, 25)
165-
irb(main):024:1> end
166-
=> [15, 25]
167-
```
88+
## 🛠️ よく使う組み込みクラスのメソッド
16889

169-
## yield:ブロックを受け取るメソッド
90+
すべてがオブジェクトであるため、Rubyは基本的なデータ型に対して非常に多くの便利なメソッドを標準で提供しています。
17091

171-
では、どうすればブロックを受け取るメソッドを自分で作れるのでしょうか?
172-
それには `yield` というキーワードを使います。
92+
### String (文字列)
17393

174-
メソッド内で `yield` が呼び出されると、そのメソッドに渡されたブロックが実行されます
94+
`String` クラスには、テキスト操作のための豊富なメソッドが用意されています
17595

176-
```ruby:yield_basic.rb
177-
def simple_call
178-
puts "メソッド開始"
179-
yield # ここでブロックが実行される
180-
puts "メソッド終了"
181-
end
96+
```ruby:string_methods.rb
97+
text = " ruby is convenient "
18298

183-
simple_call do
184-
puts "ブロック内の処理です"
185-
end
186-
```
99+
# 先頭と末尾の空白を除去
100+
cleaned_text = text.strip
101+
puts "Strip: '#{cleaned_text}'"
187102

188-
```ruby-exec:yield_basic.rb
189-
メソッド開始
190-
ブロック内の処理です
191-
メソッド終了
192-
```
103+
# 先頭の文字を大文字に
104+
puts "Capitalize: #{cleaned_text.capitalize}"
193105

194-
`yield` はブロックに引数を渡すこともできます。
106+
# "convenient" を "powerful" に置換
107+
puts "Gsub: #{cleaned_text.gsub("convenient", "powerful")}"
195108

196-
```ruby:yield_with_args.rb
197-
def call_with_name(name)
198-
puts "メソッド開始"
199-
yield(name) # ブロックに "Alice" を渡す
200-
yield("Bob") # ブロックに "Bob" を渡す
201-
puts "メソッド終了"
202-
end
109+
# "ruby" という文字列で始まっているか?
110+
puts "Start with 'ruby'?: #{cleaned_text.start_with?("ruby")}"
203111

204-
call_with_name("Alice") do |n|
205-
puts "ブロックが #{n} を受け取りました"
206-
end
112+
# 単語に分割 (配列が返る)
113+
words = cleaned_text.split(" ")
114+
p words # p はデバッグ用の表示メソッド
207115
```
208116

209-
```ruby-exec:yield_with_args.rb
210-
メソッド開始
211-
ブロックが Alice を受け取りました
212-
ブロックが Bob を受け取りました
213-
メソッド終了
117+
```ruby-exec:string_methods.rb
118+
Strip: 'ruby is convenient'
119+
Capitalize: Ruby is convenient
120+
Gsub: ruby is powerful
121+
Start with 'ruby'?: true
122+
["ruby", "is", "convenient"]
214123
```
215124

216-
`each``map` のようなイテレータは、内部でこの `yield` を使って、コレクションの各要素をブロックに渡しながら実行しているのです。
217-
218-
## この章のまとめ
125+
### Integer / Float (数値)
219126

220-
* **ブロック**は、メソッドに渡せるコードの塊で、`{}`(1行)または `do...end`(複数行)で記述します。
221-
* **イテレータ**は、ブロックを受け取り、要素の繰り返し処理を行うメソッドです(`each`, `map`, `select` など)。
222-
* Rubyでは `for` ループよりもイテレータが好まれます。
223-
* ブロックは `|arg|` で引数を受け取ることができ、ブロックの最後の式の値が戻り値となります。
224-
* 自作メソッド内で `yield` を使うと、渡されたブロックを実行できます。
127+
数値クラス (総称して `Numeric`) も便利なメソッドを持っています。
225128

226-
### 練習問題1
227-
228-
数値の配列 `[1, 2, 3, 4, 5]` があります。`map` イテレータとブロックを使って、各要素を文字列に変換し(例: `1``"1"`)、 `"1"`, `"2"`, `"3"`, `"4"`, `"5"` という文字列の配列を作成してください。
129+
```ruby-repl:7
130+
irb(main):001:0> # Integer
131+
irb(main):002:0> 10.even?
132+
=> true
133+
irb(main):003:0> 10.odd?
134+
=> false
135+
irb(main):004:0> 5.to_s
136+
=> "5"
137+
irb(main):005:0> 5.to_f
138+
=> 5.0
139+
140+
irb(main):006:0> # Float
141+
irb(main):007:0> 10.5.round
142+
=> 11
143+
irb(main):008:0> 10.5.floor # 切り捨て
144+
=> 10
145+
irb(main):009:0> 10.5.ceil # 切り上げ
146+
=> 11
147+
irb(main):010:0> (10.5).to_i
148+
=> 10
149+
```
150+
151+
## 📜 この章のまとめ
152+
153+
* Rubyでは、数値、文字列、`nil` を含むすべてが **オブジェクト** です。
154+
* すべてのオブジェクトは **クラス** に属しています(例: `5``Integer` クラス)。
155+
* オブジェクトであるため、すべての値は **メソッド** を持つことができます(例: `5.times`, `"hello".upcase`)。
156+
* メソッド呼び出しは、オブジェクトへの **メッセージパッシング** として理解されます。
157+
* `nil``NilClass` のオブジェクトであり、メソッドを持ちます。
158+
159+
### 練習問題1: 文字列の操作
160+
変数 `sentence = " Welcome to the Ruby World! "` があります。`String` のメソッドを組み合わせて、最終的に `"WELCOME, RUBY"` という文字列をコンソールに出力してください。
161+
162+
* ヒント: `strip`, `upcase`, `gsub` (または `sub`), `slice` (またはインデックスアクセス `[]`) などが使えます。
229163

230164
```ruby:practice4_1.rb
231-
array = [1, 2, 3, 4, 5]
232-
165+
sentence = " Welcome to the Ruby World! "
233166
```
234167

235168
```ruby-exec:practice4_1.rb
236169
```
237170

238-
### 練習問題2
239-
文字列の配列 `["apple", "banana", "cherry", "date"]` があります。`select` イテレータとブロックを使って、文字数が5文字以上の果物だけを抽出した新しい配列(`["apple", "banana", "cherry"]`)を作成してください。
240171

241-
```ruby:practice4_2.rb
242-
array = ["apple", "banana", "cherry", "date"]
172+
### 練習問題2: 数値と判定
243173

174+
`Float` の値 `123.456` があります。この値を四捨五入して整数(`Integer`)にした後、その整数が偶数(even)か奇数(odd)かを判定して、`"Result is even"` または `"Result is odd"` と出力するコードを書いてください。
175+
176+
```ruby:practice4_2.rb
177+
value = 123.456
244178
```
245179

246180
```ruby-exec:practice4_2.rb

0 commit comments

Comments
 (0)