From a84908b7e8a0e2423afd6b836eccf27a420270b4 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Wed, 20 Sep 2023 19:56:52 +0900 Subject: feat(blog/nuldoc): change content format from DocBook to NulDoc --- .../2021-10-02/ruby-then-keyword-and-case-in.ndoc | 266 +++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 vhosts/blog/content/posts/2021-10-02/ruby-then-keyword-and-case-in.ndoc (limited to 'vhosts/blog/content/posts/2021-10-02/ruby-then-keyword-and-case-in.ndoc') diff --git a/vhosts/blog/content/posts/2021-10-02/ruby-then-keyword-and-case-in.ndoc b/vhosts/blog/content/posts/2021-10-02/ruby-then-keyword-and-case-in.ndoc new file mode 100644 index 00000000..994b1d7d --- /dev/null +++ b/vhosts/blog/content/posts/2021-10-02/ruby-then-keyword-and-case-in.ndoc @@ -0,0 +1,266 @@ +--- +[article] +title = "【Ruby】 then キーワードと case in" +description = "Ruby 3.0 で追加される case in 構文と、then キーワードについて。" +tags = [ + "ruby", + "ruby3", +] + +[[article.revisions]] +date = "2021-10-02" +remark = "Qiita から移植" +--- +
+ + この記事は Qiita から移植してきたものです。 + 元 URL: https://qiita.com/nsfisis/items/787a8cf888a304497223 + +
+ TL; DR +

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

+
+
+ then とは +

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

+ + + +

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

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

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

+ + + +

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

+ + + +

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

+

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

+ + + +

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

+
+
+ なぜ then; や改行が必要か +

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

+ + + +

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

+ + + + + + +

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

+

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

+
+
+ case - in における then +

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

+

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

+ + command_start = FALSE; + $1 = p->ctxt; + p->ctxt.in_kwarg = 1; + $$ = push_pvtbl(p); + } + { + $$ = push_pktbl(p); + } + p_top_expr then + { + pop_pktbl(p, $3); + pop_pvtbl(p, $2); + p->ctxt.in_kwarg = $1.in_kwarg; + } + compstmt + p_cases + { + /*%%%*/ + $$ = NEW_IN($4, $7, $8, &@$); + /*% %*/ + /*% ripper: in!($4, $7, escape_Qundef($8)) %*/ + } + ; + ]]> + +

+ 簡略版: +

+ + + +

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

+

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

+ + + +

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

+ + + +
+
+ まとめ +
    +
  • + ifcase の条件の後ろには then;、改行のいずれかが必要 +
      +
    • 通常は改行しておけばよい
    • +
    +
  • +
  • 3.0 で入る予定の case - in でも then 等が必要になる
  • +
  • Ruby の構文を正確に知るには (現状) parse.y を直接読めばよい
  • +
+
+
-- cgit v1.2.3-70-g09d2