From 88b66f82aae2d7784002b07bfc7877932da3ec94 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 19 Mar 2023 00:47:11 +0900 Subject: fix(content): fix XML notations --- .../ruby-then-keyword-and-case-in/index.html | 82 +++++++++++----------- 1 file changed, 41 insertions(+), 41 deletions(-) (limited to 'public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html') diff --git a/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html b/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html index 31107fc..097d417 100644 --- a/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html +++ b/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html @@ -9,7 +9,7 @@ 【Ruby】 then キーワードと case in | REPL: Rest-Eat-Program Loop - + @@ -57,7 +57,7 @@

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

@@ -68,58 +68,58 @@

TL; DR

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

then とは

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

if cond then
   puts "Y"
-  else
+else
   puts "N"
-  end
+end

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

# Example:
 
 if x then
-a
+  a
 end
 
 unless x then
-a
+  a
 end
 
 begin
-a
+  a
 rescue then
-b
+  b
 end
 
 case x
 when p then
-a
+  a
 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'
@@ -129,31 +129,31 @@ if true puts 'Hello, World!' end
 ...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 等」) が必要なのだろうか。次の例を見てほしい:

if a b end

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

# a という変数かメソッドの評価結果が truthy なら b という変数かメソッドを評価
@@ -167,18 +167,18 @@ b
 end

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

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

case - in における then

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

@@ -186,45 +186,45 @@ b

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

- 簡略版: + 簡略版:

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
@@ -235,11 +235,11 @@ b
 
 case x
 in 1
-a
+  a
 in 2
-b
+  b
 in 3
-c
+  c
 end
 
 case x
@@ -249,7 +249,7 @@ c
 end

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

case x
-- 
cgit v1.2.3-70-g09d2