diff options
| author | nsfisis <nsfisis@gmail.com> | 2023-03-15 01:36:13 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2023-03-15 01:36:58 +0900 |
| commit | 98682c7a8792e7e79e487fea5024d25cee5aa310 (patch) | |
| tree | fbf975077f5c1a6ff4f9eee68e4a4908eb7f54a0 /public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html | |
| parent | 1fa2ed103dc521698cff261c97ecf275708be58c (diff) | |
| download | blog.nsfisis.dev-98682c7a8792e7e79e487fea5024d25cee5aa310.tar.gz blog.nsfisis.dev-98682c7a8792e7e79e487fea5024d25cee5aa310.tar.zst blog.nsfisis.dev-98682c7a8792e7e79e487fea5024d25cee5aa310.zip | |
fix(nuldoc): <pre> contained unnecessary whitespaces inside it
Diffstat (limited to 'public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html')
| -rw-r--r-- | public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html | 68 |
1 files changed, 22 insertions, 46 deletions
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 9b1df47..ed8d9e8 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 @@ -65,20 +65,17 @@ 使われることは稀だが、Ruby では<code>then</code>がキーワードになっている。次のように使う: </p> - <pre class="highlight" language="ruby" linenumbering="unnumbered"> - <code>if cond then + <pre class="highlight" language="ruby" linenumbering="unnumbered"><code>if cond then puts "Y" else puts "N" - end</code> - </pre> + end</code></pre> <p> このキーワードが現れうる場所はいくつかあり、<code>if</code>、<code>unless</code>、<code>rescue</code>、<code>case</code>構文がそれに当たる。 上記のように、何か条件を書いた後<code>then</code>を置き、式がそこで終了していることを示すマーカーとして機能する。 </p> - <pre class="highlight" language="ruby" linenumbering="unnumbered"> - <code># Example: + <pre class="highlight" language="ruby" linenumbering="unnumbered"><code># Example: if x then a @@ -97,8 +94,7 @@ end case x when p then a -end</code> - </pre> +end</code></pre> </section> <section id="section--_なぜ普段は書かなくてもよいのか"> @@ -107,21 +103,17 @@ end</code> 普通 Ruby のコードで<code>then</code>を書くことはない。なぜか。次のコードを実行してみるとわかる。 </p> - <pre class="highlight" language="ruby" linenumbering="unnumbered"> - <code>if true puts 'Hello, World!' end</code> - </pre> + <pre class="highlight" language="ruby" linenumbering="unnumbered"><code>if true puts 'Hello, World!' end</code></pre> <p> 次のような構文エラーが出力される。 </p> - <pre class="monospaced highlight"> - <code>20:1: syntax error, unexpected local variable or method, expecting `then' or ';' or '\n' + <pre class="monospaced highlight"><code>20:1: syntax error, unexpected local variable or method, expecting `then' or ';' or '\n' if true puts 'Hello, World!' end ^~~~ 20:1: syntax error, unexpected `end', expecting end-of-input - ...f true puts 'Hello, World!' end</code> - </pre> + ...f true puts 'Hello, World!' end</code></pre> <p> 二つ目のメッセージは無視して一つ目を読むと、<code>then</code>か<code>;</code>か改行が来るはずのところ変数だかメソッドだかが現れたことによりエラーとなっているようだ。 @@ -131,10 +123,8 @@ end</code> ポイントは改行が<code>then</code>(や<code>;</code>) の代わりとなることである。<code>true</code>の後に改行を入れてみる。 </p> - <pre class="highlight" language="ruby" linenumbering="unnumbered"> - <code>if true -puts 'Hello, World!' end</code> - </pre> + <pre class="highlight" language="ruby" linenumbering="unnumbered"><code>if true +puts 'Hello, World!' end</code></pre> <p> 無事 Hello, World! と出力されるようになった。 @@ -147,27 +137,21 @@ puts 'Hello, World!' end</code> なぜ<code>then</code>や<code>;</code>や改行 (以下 「<code>then</code>等」) が必要なのだろうか。次の例を見てほしい: </p> - <pre class="highlight" language="ruby" linenumbering="unnumbered"> - <code>if a b end</code> - </pre> + <pre class="highlight" language="ruby" linenumbering="unnumbered"><code>if a b end</code></pre> <p> <code>then</code>も<code>;</code>も改行もないのでエラーになるが、これは条件式がどこまで続いているのかわからないためだ。 この例は二通りに解釈できる。 </p> - <pre class="highlight" language="ruby" linenumbering="unnumbered"> - <code># a という変数かメソッドの評価結果が truthy なら b という変数かメソッドを評価 + <pre class="highlight" language="ruby" linenumbering="unnumbered"><code># a という変数かメソッドの評価結果が truthy なら b という変数かメソッドを評価 if a then b -end</code> - </pre> +end</code></pre> - <pre class="highlight" language="ruby" linenumbering="unnumbered"> - <code># a というメソッドに b という変数かメソッドの評価結果を渡して呼び出し、 + <pre class="highlight" language="ruby" linenumbering="unnumbered"><code># a というメソッドに b という変数かメソッドの評価結果を渡して呼び出し、 # その結果が truthy なら何もしない if a(b) then -end</code> - </pre> +end</code></pre> <p> <code>then</code>等はこの曖昧性を排除するためにあり、条件式は<code>if</code>から<code>then</code>等までの間にある、ということを明確にする。 C系の<code>if</code>後に来る<code>(</code>/<code>)</code>や、Python の<code>:</code>、Rust/Go/Swift などの<code>{</code>も同じ役割を持つ。 @@ -188,8 +172,7 @@ end</code> <a href="https://github.com/ruby/ruby/blob/221ca0f8281d39f0dfdfe13b2448875384bbf735/parse.y#L3961-L3986">https://github.com/ruby/ruby/blob/221ca0f8281d39f0dfdfe13b2448875384bbf735/parse.y#L3961-L3986</a> </p> - <pre class="highlight" language="yacc" linenumbering="unnumbered"> - <code>p_case_body : keyword_in + <pre class="highlight" language="yacc" linenumbering="unnumbered"><code>p_case_body : keyword_in { SET_LEX_STATE(EXPR_BEG|EXPR_LABEL); p->command_start = FALSE; @@ -214,17 +197,14 @@ end</code> /*% %*/ /*% ripper: in!($4, $7, escape_Qundef($8)) %*/ } - ;</code> - </pre> + ;</code></pre> <p> 簡略版: </p> - <pre class="highlight" language="yacc" linenumbering="unnumbered"> - <code>p_case_body : keyword_in p_top_expr then compstmt p_cases -;</code> - </pre> + <pre class="highlight" language="yacc" linenumbering="unnumbered"><code>p_case_body : keyword_in p_top_expr then compstmt p_cases +;</code></pre> <p> ここで、<code>keyword_in</code>は文字通り<code>in</code>、<code>p_top_expr</code>はいわゆるパターン、<code>then</code>は<code>then</code>キーワードのことではなく、この記事で<code>then</code>等と呼んでいるもの、つまり<code>then</code>キーワード、<code>;</code>、改行のいずれかである。 @@ -234,8 +214,7 @@ end</code> これにより、<code>case</code>-<code>when</code>による従来の構文と同じように、<code>then</code>等をパターンの後ろに挿入すればよいことがわかった。つまり次の3通りのいずれかになる: </p> - <pre class="highlight" language="ruby" linenumbering="unnumbered"> - <code>case x + <pre class="highlight" language="ruby" linenumbering="unnumbered"><code>case x in 1 then a in 2 then b in 3 then c @@ -254,20 +233,17 @@ case x in 1; a in 2; b in 3; c -end</code> - </pre> +end</code></pre> <p> ところで、<code>p_top_expr</code>には<code>if</code>による guard clause が書けるので、その場合は<code>if</code>-<code>then</code>と似たような見た目になる。 </p> - <pre class="highlight" language="ruby" linenumbering="unnumbered"> - <code>case x + <pre class="highlight" language="ruby" linenumbering="unnumbered"><code>case x in 0 then a in n if n < 0 then b in n then c -end</code> - </pre> +end</code></pre> </section> <section id="section--_まとめ"> |
