Skip to content

Commit f0b8818

Browse files
committed
10章まで
1 parent b850960 commit f0b8818

File tree

6 files changed

+974
-5
lines changed

6 files changed

+974
-5
lines changed

public/docs/ruby-1.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ Welcome!
100100
=> 3
101101
```
102102

103-
`=>` の右側に表示されているのが、式の\*\*評価結果(返り値)\*\*です。
103+
`=>` の右側に表示されているのが、式の**評価結果(返り値)**です。
104104

105105
`3.times`の例に注目してください。`puts "Welcome!"`が3回実行(出力)されていますが、`=> 3`と表示されています。これは、`3.times`というメソッド自体の返り値が`3`(レシーバである数値)であることを示しています。Rubyではすべての式が値を返すことを覚えておいてください。
106106

public/docs/ruby-10.md

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
# 第10章: 標準ライブラリの活用
2+
3+
Rubyの強力な点の一つは、多くの一般的なタスクを処理するための豊富な「標準ライブラリ」が同梱されていることです。これらは "batteries included"(電池付属)とよく表現されます。
4+
5+
他の言語で `import``include` を使うのと同様に、Rubyでは `require` を使ってこれらのライブラリをロードします。ただし、`File``Time``Regexp` のようなコア機能の多くは、`require` なしで利用可能です。
6+
7+
この章では、特に使用頻度の高い標準ライブラリの機能を見ていきます。
8+
9+
## ファイル操作 (File, Dir, Pathname)
10+
11+
ファイルシステムとのやり取りは、多くのアプリケーションで不可欠です。
12+
13+
### Fileクラスによる読み書き
14+
15+
`File` クラスは、ファイルに対する基本的な読み書き操作を提供します。
16+
17+
**ファイルの書き込みと追記:**
18+
19+
```ruby:file_io_example.rb
20+
# 1. ファイルへの書き込み (上書き)
21+
# シンプルな方法は File.write です
22+
File.write('sample.txt', "Hello, Ruby Standard Library!\n")
23+
24+
# 2. ファイルへの追記
25+
# mode: 'a' (append) オプションを指定します
26+
File.write('sample.txt', "This is a second line.\n", mode: 'a')
27+
28+
puts "File 'sample.txt' created and updated."
29+
```
30+
31+
```ruby-exec:file_io_example.rb
32+
File 'sample.txt' created and updated.
33+
```
34+
35+
```text-readonly:sample.txt
36+
```
37+
38+
**ファイルの読み込み:**
39+
40+
```ruby:file_read_example.rb
41+
# 'sample.txt' が存在すると仮定
42+
43+
# 1. ファイル全体を一度に読み込む
44+
content = File.read('sample.txt')
45+
puts "--- Reading all at once ---"
46+
puts content
47+
48+
# 2. 1行ずつ処理する (大きなファイルに効率的)
49+
puts "\n--- Reading line by line ---"
50+
File.foreach('sample.txt') do |line|
51+
print "Line: #{line}"
52+
end
53+
54+
# 3. 処理後にファイルをクリーンアップ
55+
File.delete('sample.txt')
56+
puts "\n\nFile 'sample.txt' deleted."
57+
```
58+
59+
```ruby-exec:file_read_example.rb
60+
--- Reading all at once ---
61+
Hello, Ruby Standard Library!
62+
This is a second line.
63+
64+
--- Reading line by line ---
65+
Line: Hello, Ruby Standard Library!
66+
Line: This is a second line.
67+
68+
File 'sample.txt' deleted.
69+
```
70+
71+
### DirクラスとPathname
72+
73+
`Dir` クラスはディレクトリの内容を操作するために使われます。特に `Dir.glob` はワイルドカードを使ってファイルやディレクトリを検索するのに便利です。
74+
75+
しかし、パスの連結や解析を文字列として扱うのは面倒です。`Pathname` ライブラリは、パスをオブジェクトとして扱うための優れたインターフェースを提供します。
76+
77+
```ruby-repl:1
78+
irb(main):001:0> # Dir.glob はワイルドカードでファイルリストを取得できます
79+
irb(main):002:0> Dir.glob('*.rb') # (irbを実行しているディレクトリによります)
80+
=> []
81+
82+
irb(main):003:0> # Pathname を使うには require が必要
83+
irb(main):004:0> require 'pathname'
84+
=> true
85+
86+
irb(main):005:0> # 文字列の代わりに Pathname オブジェクトを作成
87+
irb(main):006:0> base_path = Pathname.new('/usr/local')
88+
=> #<Pathname:/usr/local>
89+
90+
irb(main):007:0> # + や / 演算子で安全にパスを連結できます
91+
irb(main):008:0> lib_path = base_path + 'lib'
92+
=> #<Pathname:/usr/local/lib>
93+
irb(main):009:0> bin_path = base_path / 'bin'
94+
=> #<Pathname:/usr/local/bin>
95+
96+
irb(main):010:0> # パスの解析
97+
irb(main):011:0> file_path = Pathname.new('/var/log/app.log')
98+
=> #<Pathname:/var/log/app.log>
99+
irb(main):012:0> file_path.basename # ファイル名
100+
=> #<Pathname:app.log>
101+
irb(main):013:0> file_path.extname # 拡張子
102+
=> ".log"
103+
irb(main):014:0> file_path.dirname # 親ディレクトリ
104+
=> #<Pathname:/var/log>
105+
irb(main):015:0> file_path.absolute? # 絶対パスか?
106+
=> true
107+
```
108+
109+
## 日付と時刻 (Time, Date)
110+
111+
Rubyには `Time`(組み込み)と `Date`(要 `require`)の2つの主要な日時クラスがあります。
112+
113+
* **Time:** 時刻(タイムスタンプ)をナノ秒までの精度で扱います。
114+
* **Date:** 日付(年月日)のみを扱い、カレンダー計算に特化しています。
115+
116+
```ruby-repl:2
117+
irb(main):001:0> # Time (組み込み)
118+
irb(main):002:0> now = Time.now
119+
=> 2025-11-04 11:32:00 +0900 (JST)
120+
irb(main):003:0> now.year
121+
=> 2025
122+
irb(main):004:0> now.monday?
123+
=> false
124+
irb(main):005:0> now.to_i # UNIXタイムスタンプ
125+
=> 1762309920
126+
127+
irb(main):006:0> # strftime (string format time) でフォーマット
128+
irb(main):007:0> now.strftime("%Y-%m-%d %H:%M:%S")
129+
=> "2025-11-04 11:32:00"
130+
131+
irb(main):008:0> # Date (require が必要)
132+
irb(main):009:0> require 'date'
133+
=> true
134+
irb(main):010:0> today = Date.today
135+
=> #<Date: 2025-11-04 ((2461014j,0s,0n),+0s,2299161j)>
136+
irb(main):011:0> today.strftime("%A") # 曜日
137+
=> "Tuesday"
138+
139+
irb(main):012:0> # 文字列からのパース
140+
irb(main):013:0> christmas = Date.parse("2025-12-25")
141+
=> #<Date: 2025-12-25 ((2461065j,0s,0n),+0s,2299161j)>
142+
irb(main):014:0> (christmas - today).to_i # あと何日?
143+
=> 51
144+
```
145+
146+
## JSONのパースと生成 (json)
147+
148+
現代のWeb開発においてJSONの扱いは不可欠です。`json` ライブラリは、JSON文字列とRubyのHash/Arrayを相互に変換する機能を提供します。
149+
150+
```ruby-repl:3
151+
irb(main):001:0> require 'json'
152+
=> true
153+
154+
irb(main):002:0> # 1. JSON文字列 -> Rubyオブジェクト (Hash) へのパース
155+
irb(main):003:0> json_data = '{"user_id": 123, "name": "Alice", "tags": ["admin", "ruby"]}'
156+
=> "{\"user_id\": 123, \"name\": \"Alice\", \"tags\": [\"admin\", \"ruby\"]}"
157+
158+
irb(main):004:0> parsed_data = JSON.parse(json_data)
159+
=> {"user_id"=>123, "name"=>"Alice", "tags"=>["admin", "ruby"]}
160+
irb(main):005:0> parsed_data['name']
161+
=> "Alice"
162+
irb(main):006:0> parsed_data['tags']
163+
=> ["admin", "ruby"]
164+
165+
irb(main):007:0> # 2. Rubyオブジェクト (Hash) -> JSON文字列 への生成
166+
irb(main):008:0> ruby_hash = {
167+
irb(main):009:1* status: "ok",
168+
irb(main):010:1* data: { item_id: 987, price: 1500 }
169+
irb(main):011:1* }
170+
=> {:status=>"ok", :data=>{:item_id=>987, :price=>1500}}
171+
172+
irb(main):012:0> # .to_json メソッドが便利です
173+
irb(main):013:0> json_output = ruby_hash.to_json
174+
=> "{\"status\":\"ok\",\"data\":{\"item_id\":987,\"price\":1500}}"
175+
176+
irb(main):014:0> # 人が読みやすいように整形 (pretty generate)
177+
irb(main):015:0> puts JSON.pretty_generate(ruby_hash)
178+
{
179+
"status": "ok",
180+
"data": {
181+
"item_id": 987,
182+
"price": 1500
183+
}
184+
}
185+
=> nil
186+
```
187+
188+
## 正規表現 (Regexp) と match
189+
190+
Rubyの正規表現 (Regexp) は、Perl互換の強力なパターンマッチング機能を提供します。`/pattern/` リテラルで記述するのが一般的です。
191+
192+
### マッチの確認 (`=~``match`)
193+
194+
* `=~` 演算子: マッチした位置のインデックス(0から始まる)を返すか、マッチしなければ `nil` を返します。
195+
* `String#match`: `MatchData` オブジェクトを返すか、マッチしなければ `nil` を返します。`MatchData` は、キャプチャグループ(`()`で囲んだ部分)へのアクセスに便利です。
196+
197+
```ruby-repl:4
198+
irb(main):001:0> text = "User: [email protected] (Alice Smith)"
199+
=> "User: [email protected] (Alice Smith)"
200+
201+
irb(main):002:0> # =~ は位置を返す
202+
irb(main):003:0> text =~ /alice/
203+
=> 6
204+
irb(main):004:0> text =~ /bob/
205+
=> nil
206+
207+
irb(main):005:0> # String#match は MatchData を返す
208+
irb(main):006:0> # パターン: (ユーザー名)@(ドメイン)
209+
irb(main):007:0> match_data = text.match(/(\w+)@([\w\.]+)/)
210+
=> #<MatchData "[email protected]" 1:"alice" 2:"example.com">
211+
212+
irb(main):008:0> # マッチしたオブジェクトからキャプチャを取得
213+
irb(main):009:0> match_data[0] # マッチ全体
214+
215+
irb(main):010:0> match_data[1] # 1番目の ()
216+
=> "alice"
217+
irb(main):011:0> match_data[2] # 2番目の ()
218+
=> "example.com"
219+
```
220+
221+
### 検索と置換 (`scan``gsub`)
222+
223+
* `String#scan`: マッチするすべての部分文字列を(キャプチャグループがあればその配列として)返します。
224+
* `String#gsub`: マッチするすべての部分を置換します (Global SUBstitute)。
225+
226+
```ruby-repl:5
227+
irb(main):001:0> log = "ERROR: code 500. WARNING: code 404. ERROR: code 403."
228+
=> "ERROR: code 500. WARNING: code 404. ERROR: code 403."
229+
230+
irb(main):002:0> # scan: 'ERROR: code (数字)' にマッチする部分をすべて探す
231+
irb(main):003:0> log.scan(/ERROR: code (\d+)/)
232+
=> [["500"], ["403"]]
233+
234+
irb(main):004:0> # gsub: 'ERROR' を 'CRITICAL' に置換する
235+
irb(main):005:0> log.gsub("ERROR", "CRITICAL")
236+
=> "CRITICAL: code 500. WARNING: code 404. CRITICAL: code 403."
237+
238+
irb(main):006:0> # gsub はブロックと正規表現を組み合わせて高度な置換が可能
239+
irb(main):007:0> # 数字(コード)を [] で囲む
240+
irb(main):008:0> log.gsub(/code (\d+)/) do |match|
241+
irb(main):009:1* # $1 は最後のマッチの1番目のキャプチャグループ
242+
irb(main):010:1* "code [#{$1}]"
243+
irb(main):011:1> end
244+
=> "ERROR: code [500]. WARNING: code [404]. ERROR: code [403]."
245+
```
246+
247+
## この章のまとめ
248+
249+
* Rubyには、`require` でロードできる豊富な**標準ライブラリ**が付属しています。
250+
* **File**クラスはファイルの読み書きを、**Pathname**はパス操作をオブジェクト指向的に行います。
251+
* **Time**は時刻を、**Date**は日付を扱います。`strftime` でフォーマットできます。
252+
* **json**ライブラリは `JSON.parse`(文字列→Hash)と `to_json`(Hash→文字列)を提供します。
253+
* **Regexp**`/pattern/`)はパターンマッチングに使います。`String#match``MatchData` を取得し、`scan``gsub` で検索・置換を行います。
254+
255+
これらは標準ライブラリのごく一部です。他にもCSVの処理 (`csv`)、HTTP通信 (`net/http`)、テスト (`minitest`) など、多くの機能が提供されています。
256+
257+
### 練習問題1: JSON設定ファイルの読み書き
258+
259+
1. `config.json` ファイルを読み込み、内容をJSONパースしてRubyのHashに変換してください。
260+
2. そのHashの `logging` の値を `true` に変更し、さらに `:updated_at` というキーで現在時刻(文字列)を追加してください。
261+
3. 変更後のHashをJSON文字列に変換し、`config_updated.json` という名前でファイルに保存してください。(読みやすさのために `JSON.pretty_generate` を使っても構いません)
262+
263+
```json-readonly:config.json
264+
{"app_name": "RubyApp", "version": "1.0", "logging": false}
265+
```
266+
267+
```ruby:practice10_1.rb
268+
```
269+
270+
```ruby-exec:practice10_1.rb
271+
```
272+
273+
```json-readonly:config_updated.json
274+
```
275+
276+
### 練習問題2: ログファイルからの情報抽出
277+
278+
1. `system.log` というファイルを1行ずつ読み込みます。
279+
2. 正規表現を使い、`[INFO]` で始まり、かつ `logged in` という文字列を含む行だけを検出してください。
280+
3. マッチした行から、IPアドレス(`192.168.1.10` のような形式)を正規表現のキャプチャグループを使って抽出し、IPアドレスだけをコンソールに出力してください。
281+
282+
```text-readonly:system.log
283+
[INFO] 2025-11-04 User 'admin' logged in from 192.168.1.10
284+
[WARN] 2025-11-04 Failed login attempt for user 'guest'
285+
[INFO] 2025-11-04 Service 'payment_gateway' started.
286+
```
287+
288+
```ruby:practice10_2.rb
289+
```
290+
291+
```ruby-exec:practice10_2.rb
292+
```

public/docs/ruby-3.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Rubyの制御構造は、他の多くの言語と似ていますが、Rubyの「
44

55
## 条件分岐
66

7-
Rubyの条件分岐は、`if``unless``case`が基本です。`if``case`は文(Statement)ではなく\*\*式(Expression)\*\*であるため、それ自体が値を返します。
7+
Rubyの条件分岐は、`if``unless``case`が基本です。`if``case`は文(Statement)ではなく**式(Expression)**であるため、それ自体が値を返します。
88

99
### if, else, elsif
1010

0 commit comments

Comments
 (0)