aboutsummaryrefslogtreecommitdiffhomepage
path: root/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html
diff options
context:
space:
mode:
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.html108
1 files changed, 54 insertions, 54 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 49127f6..f66ae0b 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
@@ -10,7 +10,7 @@
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<title>【Ruby】 then キーワードと case in | REPL: Rest-Eat-Program Loop</title>
<link rel="stylesheet" href="/style.css?h=17cf97a767ec5fb6e64967729f40f30a">
- <link rel="stylesheet" href="/hl.css?h=208c52e3b7c9db1cad782c5d30b4698f">
+ <link rel="stylesheet" href="/hl.css?h=340e65ffd5c17713efc9107c06304f7b">
</head>
<body class="single">
<header class="header">
@@ -75,36 +75,36 @@
使われることは稀だが、Ruby では<code>then</code>がキーワードになっている。次のように使う:
</p>
- <pre class="highlight" language="ruby" linenumbering="unnumbered"><code>if cond then
- puts &quot;Y&quot;
- else
- puts &quot;N&quot;
- end</code></pre>
+ <pre class="highlight" language="ruby" linenumbering="unnumbered"><code class="highlight"><span class="hljs-keyword">if</span> cond <span class="hljs-keyword">then</span>
+ puts <span class="hljs-string">&quot;Y&quot;</span>
+ <span class="hljs-keyword">else</span>
+ puts <span class="hljs-string">&quot;N&quot;</span>
+ <span class="hljs-keyword">end</span></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 class="highlight"><span class="hljs-comment"># Example:</span>
-if x then
+<span class="hljs-keyword">if</span> x <span class="hljs-keyword">then</span>
a
-end
+<span class="hljs-keyword">end</span>
-unless x then
+<span class="hljs-keyword">unless</span> x <span class="hljs-keyword">then</span>
a
-end
+<span class="hljs-keyword">end</span>
-begin
+<span class="hljs-keyword">begin</span>
a
-rescue then
+<span class="hljs-keyword">rescue</span> <span class="hljs-keyword">then</span>
b
-end
+<span class="hljs-keyword">end</span>
-case x
-when p then
+<span class="hljs-keyword">case</span> x
+<span class="hljs-keyword">when</span> p <span class="hljs-keyword">then</span>
a
-end</code></pre>
+<span class="hljs-keyword">end</span></code></pre>
</section>
<section id="section--_なぜ普段は書かなくてもよいのか">
@@ -113,17 +113,17 @@ end</code></pre>
普通 Ruby のコードで<code>then</code>を書くことはない。なぜか。次のコードを実行してみるとわかる。
</p>
- <pre class="highlight" language="ruby" linenumbering="unnumbered"><code>if true puts &apos;Hello, World!&apos; end</code></pre>
+ <pre class="highlight" language="ruby" linenumbering="unnumbered"><code class="highlight"><span class="hljs-keyword">if</span> <span class="hljs-literal">true</span> puts <span class="hljs-string">&#x27;Hello, World!&#x27;</span> <span class="hljs-keyword">end</span></code></pre>
<p>
次のような構文エラーが出力される。
</p>
- <pre class="monospaced highlight"><code>20:1: syntax error, unexpected local variable or method, expecting `then&apos; or &apos;;&apos; or &apos;\n&apos;
-if true puts &apos;Hello, World!&apos; end
+ <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&apos;, expecting end-of-input
-...f true puts &apos;Hello, World!&apos; end</code></pre>
+20:1: syntax error, unexpected `end', expecting end-of-input
+...f true puts 'Hello, World!' end</code></pre>
<p>
二つ目のメッセージは無視して一つ目を読むと、<code>then</code>か<code>;</code>か改行が来るはずのところ変数だかメソッドだかが現れたことによりエラーとなっているようだ。
@@ -133,8 +133,8 @@ if true puts &apos;Hello, World!&apos; end
ポイントは改行が<code>then</code>(や<code>;</code>) の代わりとなることである。<code>true</code>の後に改行を入れてみる。
</p>
- <pre class="highlight" language="ruby" linenumbering="unnumbered"><code>if true
-puts &apos;Hello, World!&apos; end</code></pre>
+ <pre class="highlight" language="ruby" linenumbering="unnumbered"><code class="highlight"><span class="hljs-keyword">if</span> <span class="hljs-literal">true</span>
+puts <span class="hljs-string">&#x27;Hello, World!&#x27;</span> <span class="hljs-keyword">end</span></code></pre>
<p>
無事 Hello, World! と出力されるようになった。
@@ -147,21 +147,21 @@ puts &apos;Hello, World!&apos; end</code></pre>
なぜ<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 class="highlight"><span class="hljs-keyword">if</span> a b <span class="hljs-keyword">end</span></code></pre>
<p>
<code>then</code>も<code>;</code>も改行もないのでエラーになるが、これは条件式がどこまで続いているのかわからないためだ。 この例は二通りに解釈できる。
</p>
- <pre class="highlight" language="ruby" linenumbering="unnumbered"><code># a という変数かメソッドの評価結果が truthy なら b という変数かメソッドを評価
-if a then
+ <pre class="highlight" language="ruby" linenumbering="unnumbered"><code class="highlight"><span class="hljs-comment"># a という変数かメソッドの評価結果が truthy なら b という変数かメソッドを評価</span>
+<span class="hljs-keyword">if</span> a <span class="hljs-keyword">then</span>
b
-end</code></pre>
+<span class="hljs-keyword">end</span></code></pre>
- <pre class="highlight" language="ruby" linenumbering="unnumbered"><code># a というメソッドに b という変数かメソッドの評価結果を渡して呼び出し、
-# その結果が truthy なら何もしない
-if a(b) then
-end</code></pre>
+ <pre class="highlight" language="ruby" linenumbering="unnumbered"><code class="highlight"><span class="hljs-comment"># a というメソッドに b という変数かメソッドの評価結果を渡して呼び出し、</span>
+<span class="hljs-comment"># その結果が truthy なら何もしない</span>
+<span class="hljs-keyword">if</span> a(b) <span class="hljs-keyword">then</span>
+<span class="hljs-keyword">end</span></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>も同じ役割を持つ。
@@ -182,7 +182,7 @@ end</code></pre>
<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 class="highlight">p_case_body : keyword_in
{
SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
p-&gt;command_start = FALSE;
@@ -213,7 +213,7 @@ end</code></pre>
簡略版:
</p>
- <pre class="highlight" language="yacc" linenumbering="unnumbered"><code>p_case_body : keyword_in p_top_expr then compstmt p_cases
+ <pre class="highlight" language="yacc" linenumbering="unnumbered"><code class="highlight">p_case_body : keyword_in p_top_expr then compstmt p_cases
;</code></pre>
<p>
@@ -224,36 +224,36 @@ end</code></pre>
これにより、<code>case</code>-<code>when</code>による従来の構文と同じように、<code>then</code>等をパターンの後ろに挿入すればよいことがわかった。つまり次の3通りのいずれかになる:
</p>
- <pre class="highlight" language="ruby" linenumbering="unnumbered"><code>case x
-in 1 then a
-in 2 then b
-in 3 then c
-end
+ <pre class="highlight" language="ruby" linenumbering="unnumbered"><code class="highlight"><span class="hljs-keyword">case</span> x
+<span class="hljs-keyword">in</span> <span class="hljs-number">1</span> <span class="hljs-keyword">then</span> a
+<span class="hljs-keyword">in</span> <span class="hljs-number">2</span> <span class="hljs-keyword">then</span> b
+<span class="hljs-keyword">in</span> <span class="hljs-number">3</span> <span class="hljs-keyword">then</span> c
+<span class="hljs-keyword">end</span>
-case x
-in 1
+<span class="hljs-keyword">case</span> x
+<span class="hljs-keyword">in</span> <span class="hljs-number">1</span>
a
-in 2
+<span class="hljs-keyword">in</span> <span class="hljs-number">2</span>
b
-in 3
+<span class="hljs-keyword">in</span> <span class="hljs-number">3</span>
c
-end
+<span class="hljs-keyword">end</span>
-case x
-in 1; a
-in 2; b
-in 3; c
-end</code></pre>
+<span class="hljs-keyword">case</span> x
+<span class="hljs-keyword">in</span> <span class="hljs-number">1</span>; a
+<span class="hljs-keyword">in</span> <span class="hljs-number">2</span>; b
+<span class="hljs-keyword">in</span> <span class="hljs-number">3</span>; c
+<span class="hljs-keyword">end</span></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
-in 0 then a
-in n if n &lt; 0 then b
-in n then c
-end</code></pre>
+ <pre class="highlight" language="ruby" linenumbering="unnumbered"><code class="highlight"><span class="hljs-keyword">case</span> x
+<span class="hljs-keyword">in</span> <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> a
+<span class="hljs-keyword">in</span> n <span class="hljs-keyword">if</span> n &lt; <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> b
+<span class="hljs-keyword">in</span> n <span class="hljs-keyword">then</span> c
+<span class="hljs-keyword">end</span></code></pre>
</section>
<section id="section--_まとめ">