From 4f46d262e6967c9c638b40f3b0246d21b7a9b9dc Mon Sep 17 00:00:00 2001 From: nsfisis Date: Wed, 9 Apr 2025 20:29:15 +0900 Subject: feat(blog/nuldoc): rebuild --- .../ruby-then-keyword-and-case-in/index.html | 85 +++++++--------------- 1 file changed, 28 insertions(+), 57 deletions(-) (limited to 'vhosts/blog/public/posts/2021-10-02/ruby-then-keyword-and-case-in') diff --git a/vhosts/blog/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html b/vhosts/blog/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html index 76f7058c..cf80ece0 100644 --- a/vhosts/blog/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html +++ b/vhosts/blog/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html @@ -65,23 +65,22 @@ NOTE
- この記事は Qiita から移植してきたものです。元 URL: https://qiita.com/nsfisis/items/787a8cf888a304497223 +

+ この記事は Qiita から移植してきたものです。 元 URL: https://qiita.com/nsfisis/items/787a8cf888a304497223 +

-
-

TL; DR

+

TL; DR

case - in によるパターンマッチング構文でも、case - when と同じように then が使える (場合によっては使う必要がある)。

-
-

then とは

+

then とは

- 使われることは稀だが、Ruby では then がキーワードになっている。次のように使う: + 使われることは稀だが、Ruby では then がキーワードになっている。次のように使う:

-
if cond then
   puts "Y"
@@ -89,11 +88,9 @@
   puts "N"
 end
-

- このキーワードが現れうる場所はいくつかあり、ifunlessrescuecase 構文がそれに当たる。 上記のように、何か条件を書いた後 then を置き、式がそこで終了していることを示すマーカーとして機能する。 + このキーワードが現れうる場所はいくつかあり、ifunlessrescuecase 構文がそれに当たる。 上記のように、何か条件を書いた後 then を置き、式がそこで終了していることを示すマーカーとして機能する。

-
# Example:
 
@@ -117,21 +114,17 @@
 end
-
-

なぜ普段は書かなくてもよいのか

+

なぜ普段は書かなくてもよいのか

- 普通 Ruby のコードで then を書くことはない。なぜか。次のコードを実行してみるとわかる。 + 普通 Ruby のコードで then を書くことはない。なぜか。次のコードを実行してみるとわかる。

-
if true puts 'Hello, World!' end
-

- 次のような構文エラーが出力される。 + 次のような構文エラーが出力される。

-
20:1: syntax error, unexpected local variable or method, expecting `then' or ';' or '\n'
 if true puts 'Hello, World!' end
@@ -139,72 +132,58 @@
 20:1: syntax error, unexpected `end', expecting end-of-input
 ...f true puts 'Hello, World!' end
-

- 二つ目のメッセージは無視して一つ目を読むと、then; か改行が来るはずのところ変数だかメソッドだかが現れたことによりエラーとなっているようだ。 + 二つ目のメッセージは無視して一つ目を読むと、then; か改行が来るはずのところ変数だかメソッドだかが現れたことによりエラーとなっているようだ。

-

- ポイントは改行が then (や ;) の代わりとなることである。true の後に改行を入れてみる。 + ポイントは改行が then (や ;) の代わりとなることである。true の後に改行を入れてみる。

-
if true
 puts 'Hello, World!' end
-

- 無事 Hello, World! と出力されるようになった。 + 無事 Hello, World! と出力されるようになった。

-
-

なぜ then; や改行が必要か

+

なぜ then; や改行が必要か

- なぜ then; や改行 (以下 「then 等」) が必要なのだろうか。次の例を見てほしい: + なぜ then; や改行 (以下 「then 等」) が必要なのだろうか。次の例を見てほしい:

-
if a b end
-

- then; も改行もないのでエラーになるが、これは条件式がどこまで続いているのかわからないためだ。この例は二通りに解釈できる。 + then; も改行もないのでエラーになるが、これは条件式がどこまで続いているのかわからないためだ。 この例は二通りに解釈できる。

-
# a という変数かメソッドの評価結果が truthy なら b という変数かメソッドを評価
 if a then
 b
 end
-
# a というメソッドに b という変数かメソッドの評価結果を渡して呼び出し、
 # その結果が truthy なら何もしない
 if a(b) then
 end
-

then 等はこの曖昧性を排除するためにあり、条件式は if から then 等までの間にある、ということを明確にする。 C系の if 後に来る (/) や、Python の :、Rust/Go/Swift などの { も同じ役割を持つ。

-

- Ruby の場合、プログラマーが書きやすいよう改行でもって then が代用できるので、ほとんどの場合 then は必要ない。 + Ruby の場合、プログラマーが書きやすいよう改行でもって then が代用できるので、ほとんどの場合 then は必要ない。

-
-

case - in における then

+

case - in における then

- ようやく本題にたどり着いた。来る Ruby 3.0 では casein キーワードを使ったパターンマッチングの構文が入る予定である。この構文でもパターン部との区切りとして then 等が必要になる。 (現在の) Ruby には formal な形式での文法仕様は存在しないので、yacc の定義ファイルを参照した (yacc の説明は省略)。 + ようやく本題にたどり着いた。来る Ruby 3.0 では casein キーワードを使ったパターンマッチングの構文が入る予定である。この構文でもパターン部との区切りとして then 等が必要になる。 (現在の) Ruby には formal な形式での文法仕様は存在しないので、yacc の定義ファイルを参照した (yacc の説明は省略)。

-

- https://github.com/ruby/ruby/blob/221ca0f8281d39f0dfdfe13b2448875384bbf735/parse.y#L3961-L3986 + https://github.com/ruby/ruby/blob/221ca0f8281d39f0dfdfe13b2448875384bbf735/parse.y#L3961-L3986

-
p_case_body : keyword_in
 {
@@ -233,24 +212,19 @@
 }
 ;
-

- 簡略版: + 簡略版:

-
p_case_body : keyword_in p_top_expr then compstmt p_cases
 ;
-

- ここで、keyword_in は文字通り inp_top_expr はいわゆるパターン、thenthen キーワードのことではなく、この記事で then 等と呼んでいるもの、つまり then キーワード、;、改行のいずれかである。 + ここで、keyword_in は文字通り inp_top_expr はいわゆるパターン、thenthen キーワードのことではなく、この記事で then 等と呼んでいるもの、つまり then キーワード、;、改行のいずれかである。

-

- これにより、case - when による従来の構文と同じように、then 等をパターンの後ろに挿入すればよいことがわかった。つまり次の3通りのいずれかになる: + これにより、case - when による従来の構文と同じように、then 等をパターンの後ろに挿入すればよいことがわかった。つまり次の3通りのいずれかになる:

-
case x
 in 1 then a
@@ -273,11 +247,9 @@
 in 3; c
 end
-

- ところで、p_top_expr には if による guard clause が書けるので、その場合は if - then と似たような見た目になる。 + ところで、p_top_expr には if による guard clause が書けるので、その場合は if - then と似たような見た目になる。

-
case x
 in 0 then a
@@ -286,23 +258,22 @@
 end
-
-

まとめ

+

まとめ