Ruby 3.4で発生する「プロを目指す人のためのRuby入門 改訂2版」との差異について

## はじめに

2024年12月25日に、Rubyの新しいバージョンであるRuby 3.4がリリースされました。

https://www.ruby-lang.org/ja/news/2024/12/25/ruby-3-4-0-released/

一方、2021年12月2日に出版した書籍「[プロを目指す人のためのRuby入門 改訂2版](https://gihyo.jp/book/2021/978-4-297-12437-3)」（通称・チェリー本。以下、本書）は執筆当時最新だったRuby 3.0を対象にしています。

本書は紙の本であるため、簡単に内容をアップデートすることができません。しかし、何もしないとどんどん内容が古くなってしまい、「本の通りやってみたけど、今使っているRubyとなんか動きが違う」ということになってしまいます。

そこで新しいRubyのバージョンがリリースされて、本書の説明と異なる部分が出てきたときは、毎回ネット上でその差異を説明するようにしています。その説明を読めば、動きが違う部分があってもきっと落ち着いて対処できるはず、という算段です。

というわけで、この記事ではRuby 3.4で発生する「プロを目指す人のためのRuby入門 改訂2版」との差異について説明します（第1版との差異ではないのでご注意ください）。

また、「プロを目指す人のためのRuby入門 改訂2版」を持っていない人でも役に立ちそうなRuby 3.4の新機能や変更点もあわせて紹介します！

なお、本文に出てくる章番号や項番号は、本書の中で使われている番号です。

### 参考: もう読みましたか？Ruby 3.1〜3.3との差異はこちら
Ruby 3.1〜3.3で発生する差異については以下の記事にまとめてあります。

https://qiita.com/jnchito/items/bbabb21a1ce3f4799b52

- 公式リファレンスのURLが変わった（1.8）
- IRB上で自動補完とドキュメント表示ができるようになった（第2章 P49のコラム「Ruby 2.7以降で使えるirbの便利機能」）
- パターンマッチのピン演算子にローカル変数以外の式も渡せるようになった（11.3.2）
- パターンマッチのピン演算子にインスタンス変数、クラス変数、グローバル変数が渡せるようになった（11.3.2）
- 1行パターンマッチが実験的機能でなくなった（11.5.2）
- debug.gemがインストール不要になった（12.4.4）
- エラーハイライト（error_highlight）が導入された（本書全般、特に第12章）
- Steepの型チェックが少し厳しくなった（13.10.2）

https://qiita.com/jnchito/items/d4562c8116bb705517e2

- TypeErrorとArgumentError発生時の表示がわかりやすくなった（本書全般、12.3.3、12.3.4）
- endキーワードに過不足がある場合のエラー表示が改善された（9.6.7、12.3.8）
- Setクラスが組み込みクラスになった（4.7.4）
- パターンマッチのfindパターンが実験的機能ではなくなった（11.3.7）
- Minitestの型情報の追加方法が変わった（13.10.2）

https://qiita.com/jnchito/items/66c7de436cfe65504700

- irbのプロンプト表示が少し変わった（1.6、本書全般）
- NoMethodErrorやNameError発生時のエラーメッセージが少し変わった（本書全般）
- 13.6節のサンプルコードが警告ではなくエラーになる

上記の記事と重複する内容はこの記事では説明しません。
ですので、まだ読まれていない方は先に上の記事を読んでから、この記事に戻ってくることをお勧めします。

それでは以下が本編です。

## 本文の説明と実行結果が異なるもの

以下で説明する内容は、Ruby 3.4で実行した場合に本書（つまりRuby 3.0）で説明している内容と実行結果が異なる部分です。

### エラーメッセージの表示形式が変わった（本書全般）

Ruby 3.4ではエラーメッセージの表示形式が少し変わりました。
以下は構文エラー(SyntaxError)が発生したときのエラーメッセージです。

```
# 本書の記述（2.2.6）
add (4, 5)
#=> syntax error, unexpected ',', expecting ')' (SyntaxError)
#   add (4, 5)
#         ^

# Ruby 3.4
add (4, 5)
#=> syntax errors found (SyntaxError)
#   > 1 | add (4, 5)
#       |       ^ expected a matching `)`
#       |       ^ unexpected ',', ignoring it
#       |       ^ unexpected ',', expecting end-of-input
#       |          ^ unexpected ')', ignoring it
#       |          ^ unexpected ')', expecting end-of-input
```

Ruby 3.4の方が情報量が増えているのですが、プログラミング初心者の人にとってはそれがかえって混乱の原因になるかもしれません。
ですが、よく見ると、Ruby 3.4でも表示している内容は本質的に同じですので、落ち着いて対処してください。

ほかにも、存在しないメソッドまたはローカル変数を参照しようとしたときのエラーメッセージも少し変わりました。

```ruby
# 本書の記述（2.2.8）
x
#=> undefined local variable or method `x' for main:Object (NameError)

# Ruby 3.4
x
#=> undefined local variable or method 'x' for main (NameError)
```

ぱっと見は同じに見えるかもしれませんが、よく見ると以下の点が変わっています。

- `x`の手前のバッククオート(`` ` ``)がシングルクオート(`'`)に変わった
- `main:Object`が`main`に変わった

こんな感じで、Ruby 3.4ではエラー発生時の内容や形式がいろいろと変わっています。
とはいえ、先ほども述べたとおり、本質的には同じ情報が出力されているので、メッセージをよく読めば本書の内容を理解する上では大きな障害にならないはずです。

### irb上で表示されるハッシュの表示形式が変わった（5章、本書全般）

Ruby 3.4ではirb上で表示されるハッシュの表示形式が変わりました。
たとえば以下は5.2節のサンプルコードをirbで実行した場合の表示です（説明の都合上、警告の表示は省略しています）。

```
# Ruby 3.0
irb(main):001> { 'japan' => 'yen', 'japan' => '円' }
=> {"japan"=>"円"}

# Ruby 3.4
irb(main):001> { 'japan' => 'yen', 'japan' => '円' }
=> {"japan" => "円"}
```

ご覧のとおり、Ruby 3.4では`=>`の前後にスペースが入るようになりました。

キーがシンボルだった場合の表示も見てみましょう。

```
# Ruby 3.0
irb(main):001> { :japan => 'yen', :us => 'dollar', :india => 'rupee' }
=> {:japan=>"yen", :us=>"dollar", :india=>"rupee"}
irb(main):002> { japan: 'yen', us: 'dollar', india: 'rupee' }
=> {:japan=>"yen", :us=>"dollar", :india=>"rupee"}

# Ruby 3.4
irb(main):001> { :japan => 'yen', :us => 'dollar', :india => 'rupee' }
=> {japan: "yen", us: "dollar", india: "rupee"}
irb(main):002> { japan: 'yen', us: 'dollar', india: 'rupee' }
=> {japan: "yen", us: "dollar", india: "rupee"}
```

Ruby 3.0では`:シンボル=>値`だったのが、Ruby 3.4では`シンボル: 値`の形式に変わりました。

なお、irb上のハッシュの表示形式が変わったのはHashクラスの`inspect`メソッドの戻り値が変わった影響です。

```ruby 
# Ruby 3.0
{ 'japan' => 'yen', 'japan' => '円' }.inspect
#=> {"japan"=>"円"}
{ :japan => 'yen', :us => 'dollar', :india => 'rupee' }.inspect
#=> {:japan=>"yen", :us=>"dollar", :india=>"rupee"}

# Ruby 3.4
{ 'japan' => 'yen', 'japan' => '円' }.inspect
#=> {"japan" => "円"}
{ :japan => 'yen', :us => 'dollar', :india => 'rupee' }.inspect
#=> {japan: "yen", us: "dollar", india: "rupee"}
```

`inspect`メソッドの役割については本書の2.12.8項を参照してください。

## irbでデータ型に基づいた入力補完ができるようになった（第2章 P49のコラム「Ruby 2.7以降で使えるirbの便利機能」）

Ruby 3.4のirbではデータ型に基づいた入力補完ができるようになりました。
たとえば以下の例では`n`がIntegerであることを考慮して`up`まで入力すると`upto`が補完候補として表示されています。

![Screenshot 2024-12-25 at 10.47.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7465/6f026259-6b37-e1bb-2551-6bc09af06012.png)

一方、以下の例では`s`がStringになるので、`up`まで入力すると`upcase`、`upcase!`、`upto`の3つが補完候補として表示されています。

![Screenshot 2024-12-25 at 10.47.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7465/997448a3-5bb4-f819-cb55-8eabf956f404.png)

### 文字列の破壊的変更が警告扱いになった（2.11.3、本書全般）
Ruby 3.4では`upcase!`メソッドのような文字列の破壊的メソッドが警告扱いになりました。
たとえば、2.11.3のコードをファイルに保存し、`-w`オプション付きで実行するとRuby 3.4では警告が出力されます。

```ruby 
# このコードをsample.rbとして保存する
a = 'ruby'
a.upcase
a.upcase!
```

```
$ ruby -w sample.rb
sample.rb:3: warning: literal string will be frozen in the future (run with --debug-frozen-string-literal for more information)
```

ただし、警告が出るのは文字列リテラル（2.2.7項を参照）を使って作成した文字列（式展開を含む場合を除く）だけです。

```ruby 
# 文字列リテラルを使って作成した文字列は警告が出る
'ruby'
"ruby"
%!ruby!
?a
<<TEXT
ruby
TEXT

# 文字列リテラルを使わずに作成した文字列は警告が出ない
123.to_s
[10, 20, 30].join
'Hi!' * 10
String.new('hello')

# 式展開を含む場合も警告が出ない
name = "Alice"
"#{name}!"
```

警告が出るケースは将来的にはエラーになるものと思われますが、現時点では具体的な時期は提示されていません。
本書のサンプルコードはRuby 3.4では問題なく動きますが、読者のみなさんが自分でコードを書く場合は`upcase!`のような破壊的メソッドをなるべく使わないようにした方が、将来の変更に強いプログラムになると思います。

その他、この仕様変更に関する詳細は以下の記事にまとめているので、もっと詳しく知りたい方はこちらをご覧ください。

https://qiita.com/jnchito/items/49827d5ce7154ad86bad

### ブロックを使わないメソッドにブロックを渡すと警告が出るようになった（10.2.1）

Ruby 3.4ではブロックを使わないメソッドにブロックを渡すと警告が出るようになりました。
たとえば、10.2.1項に載せた以下のサンプルコードは警告の対象になります。

```ruby
def greet
  puts 'おはよう'
  puts 'こんばんは'
end

# Ruby 3.4ではブロックを使わないメソッドにブロックを渡すと警告が出る
greet do
  puts 'こんにちは'
end
#=> warning: the block passed to 'Object#greet' defined at (irb):1 may be ignored
```

ただし、警告が出るのは`irb -w`や`ruby -w sample.rb`のように、`-w`オプションを付けてプログラムを実行した場合です。

また、この警告はあくまで開発者への注意喚起であり、将来的にこういった呼び出しが禁止されるわけではないようです。

## その他、Ruby 3.4で注目したい新機能や変更点

ここから下では「プロを目指す人のためのRuby入門」を読んだ方なら知っておいて損のない、注目の新機能します。

### デフォルトのブロックパラメータとして it が追加された（4.8.5項に関連）

Ruby 3.4では番号指定パラメータの `_1` と同じ役割を持つ `it` が導入されました。

```ruby
# Ruby 2.7 or higher
[1, 2, 3].map { _1 * 10 }
#=> [10, 20, 30]

# Ruby 3.4
[1, 2, 3].map { it * 10 }
#=> [10, 20, 30]
```

この仕様変更に関する詳しい内容は以下の記事を参照してください。

https://qiita.com/jnchito/items/eadb5f96e0fdff01bd71

## 他にも魅力的な新機能や変更点がたくさん！！

この記事では「プロを目指す人のためのRuby入門」の読者のみなさんが興味を持ちそうな新機能を紹介しましたが、Ruby 3.4にはこのほかにもたくさんの新機能や変更点があります。

筆者が個人的に注目している新機能や変更点については以下の記事にまとめてあるのでぜひご覧ください。

https://qiita.com/jnchito/items/eadb5f96e0fdff01bd71

より詳しい内容については以下の情報源に記載されているのでこちらも要チェックです。

https://www.ruby-lang.org/ja/news/2024/12/25/ruby-3-4-0-released/

https://github.com/ruby/ruby/blob/v3_4_0/NEWS.md

https://product.st.inc/entry/2024/12/25/154728

- [Ruby 3.4 Advent Calender](https://zenn.dev/search?q=Ruby%25203.4%2520Advent%2520Calender&order=latest)


そして、今年も2024年のクリスマスにRuby 3.4を届けてくれたMatzさんやコミッタのみなさんに感謝したいと思います。どうもありがとうございました！
みなさんもぜひRuby 3.4の新機能を試してみてください😉

## まとめ

というわけで、この記事ではRuby 3.4で発生する「プロを目指す人のためのRuby入門 改訂2版」との差異をまとめました。

Ruby 3.4ではエラーメッセージの表示形式が変わったので、エラーに不慣れなプログラミング初心者の方は「本と表示が違う！なんで！？」と思うかもしれませんが、よく見ると情報そのものは変わっていないので、エラーが出ても落ち着いて対処してほしいです。

また、文字列に対して破壊的メソッドを呼び出した場合の警告は、言語仕様の変更としてはまあまあ大きめなのですが、本書では破壊的メソッドをそこまで多用していないのと、現時点ではまだ警告止まり（しかも`-w`オプションを付けないと警告が出ない）なので、本書でRubyを学習する上では大きな障害にはならないはずです。

「プロを目指す人のためのRuby入門 改訂2版」とこの記事（と、[Ruby 3.1との差異](https://qiita.com/jnchito/items/bbabb21a1ce3f4799b52)、[Ruby 3.2との差異](https://qiita.com/jnchito/items/d4562c8116bb705517e2)、[Ruby 3.3との差異](https://qiita.com/jnchito/items/66c7de436cfe65504700)）をあわせて読めば、Ruby 3.4でもバリバリと実践的なコードが書けるはずです。まだ「プロを目指す人のためのRuby入門 改訂2版」を購入されていない方は、この機会にぜひ購入を検討してもらえると嬉しいです。みなさん、よろしくお願いします！

### PR：「プロを目指す人のためのRuby入門 改訂2版」について

「プロを目指す人のためのRuby入門 改訂2版」は、他の言語での開発経験があり、これからRubyを始めたい人や、Rubyプログラミングの経験はある程度あるものの、まだまだ自信がない人に向けて、Rubyの言語仕様や開発の現場で役立つ知識を詳しく、ていねいに解説したRubyの入門書です。

改訂2版ではRuby 3.0に完全対応し、「パターンマッチ」の章を新たに追加するなど、第1版に比べてさらに内容が充実しています。

https://gihyo.jp/book/2021/978-4-297-12437-3

改訂2版の変更点については以下のブログ記事で詳しく説明していますので、こちらのぜひチェックしてみてください。

https://blog.jnito.com/entry/2021/12/02/072804