diff options
| author | nsfisis <nsfisis@gmail.com> | 2022-08-31 23:30:53 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2022-08-31 23:32:02 +0900 |
| commit | 5d5367ed00c22cc194b8a2411b2b4b828751003b (patch) | |
| tree | 02392cbb201091853c58ffccea81dbc8f9102854 /docs/posts/2021-10-02/ruby-then-keyword-and-case-in | |
| parent | 8c071f04a749d2cf7ca7a23bff49d94738aa6b6d (diff) | |
| download | nsfisis.github.io-5d5367ed00c22cc194b8a2411b2b4b828751003b.tar.gz nsfisis.github.io-5d5367ed00c22cc194b8a2411b2b4b828751003b.tar.zst nsfisis.github.io-5d5367ed00c22cc194b8a2411b2b4b828751003b.zip | |
update hugo
Diffstat (limited to 'docs/posts/2021-10-02/ruby-then-keyword-and-case-in')
| -rw-r--r-- | docs/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html | 150 |
1 files changed, 75 insertions, 75 deletions
diff --git a/docs/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html b/docs/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html index 2ef9f05..7d62273 100644 --- a/docs/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html +++ b/docs/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html @@ -15,7 +15,7 @@ <link href="https://blog.nsfisis.dev/custom.css" rel="stylesheet"> <link rel="icon" href="https://blog.nsfisis.dev/favicon.svg"> - <meta name="generator" content="Hugo 0.88.1" /> + <meta name="generator" content="Hugo 0.102.1" /> </head> @@ -50,61 +50,61 @@ <p><code>case</code> - <code>in</code> によるパターンマッチング構文でも、<code>case</code> - <code>when</code> と同じように <code>then</code> が使える (場合によっては使う必要がある)。</p> <h1 id="then-とは"><code>then</code> とは</h1> <p>使われることは稀だが、Ruby では <code>then</code> がキーワードになっている。次のように使う:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-ruby" data-lang="ruby"><span style="color:#66d9ef">if</span> cond <span style="color:#66d9ef">then</span> - puts <span style="color:#e6db74">"Y"</span> -<span style="color:#66d9ef">else</span> - puts <span style="color:#e6db74">"N"</span> -<span style="color:#66d9ef">end</span> -</code></pre></div><p>このキーワードが現れうる場所はいくつかあり、<code>if</code>、<code>unless</code>、<code>rescue</code>、<code>case</code> 構文がそれに当たる。 +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#66d9ef">if</span> cond <span style="color:#66d9ef">then</span> +</span></span><span style="display:flex;"><span> puts <span style="color:#e6db74">"Y"</span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">else</span> +</span></span><span style="display:flex;"><span> puts <span style="color:#e6db74">"N"</span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span> +</span></span></code></pre></div><p>このキーワードが現れうる場所はいくつかあり、<code>if</code>、<code>unless</code>、<code>rescue</code>、<code>case</code> 構文がそれに当たる。 上記のように、何か条件を書いた後 <code>then</code> を置き、式がそこで終了していることを示すマーカーとして機能する。</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-ruby" data-lang="ruby"><span style="color:#75715e"># Example:</span> - -<span style="color:#66d9ef">if</span> x <span style="color:#66d9ef">then</span> - a -<span style="color:#66d9ef">end</span> - -<span style="color:#66d9ef">unless</span> x <span style="color:#66d9ef">then</span> - a -<span style="color:#66d9ef">end</span> - -<span style="color:#66d9ef">begin</span> - a -<span style="color:#66d9ef">rescue</span> <span style="color:#66d9ef">then</span> - b -<span style="color:#66d9ef">end</span> - -<span style="color:#66d9ef">case</span> x -<span style="color:#66d9ef">when</span> p <span style="color:#66d9ef">then</span> - a -<span style="color:#66d9ef">end</span> -</code></pre></div><h1 id="なぜ普段は書かなくてもよいのか">なぜ普段は書かなくてもよいのか</h1> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#75715e"># Example:</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> x <span style="color:#66d9ef">then</span> +</span></span><span style="display:flex;"><span> a +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">unless</span> x <span style="color:#66d9ef">then</span> +</span></span><span style="display:flex;"><span> a +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">begin</span> +</span></span><span style="display:flex;"><span> a +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">rescue</span> <span style="color:#66d9ef">then</span> +</span></span><span style="display:flex;"><span> b +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">case</span> x +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">when</span> p <span style="color:#66d9ef">then</span> +</span></span><span style="display:flex;"><span> a +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span> +</span></span></code></pre></div><h1 id="なぜ普段は書かなくてもよいのか">なぜ普段は書かなくてもよいのか</h1> <p>普通 Ruby のコードで <code>then</code> を書くことはない。なぜか。次のコードを実行してみるとわかる。</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-ruby" data-lang="ruby"><span style="color:#66d9ef">if</span> <span style="color:#66d9ef">true</span> puts <span style="color:#e6db74">'Hello, World!'</span> <span style="color:#66d9ef">end</span> -</code></pre></div><p>次のような構文エラーが出力される。</p> -<pre tabindex="0"><code>20:1: syntax error, unexpected local variable or method, expecting `then' or ';' or '\n' -if true puts 'Hello, World!' end +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#66d9ef">true</span> puts <span style="color:#e6db74">'Hello, World!'</span> <span style="color:#66d9ef">end</span> +</span></span></code></pre></div><p>次のような構文エラーが出力される。</p> +<pre tabindex="0"><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 +20:1: syntax error, unexpected `end', expecting end-of-input +...f true puts 'Hello, World!' end </code></pre><p>二つ目のメッセージは無視して一つ目を読むと、<code>then</code> か <code>;</code> か改行が来るはずのところ変数だかメソッドだかが現れたことによりエラーとなっているようだ。</p> <p>ポイントは改行が <code>then</code> (や <code>;</code>) の代わりとなることである。<code>true</code> の後に改行を入れてみる。</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-ruby" data-lang="ruby"><span style="color:#66d9ef">if</span> <span style="color:#66d9ef">true</span> -puts <span style="color:#e6db74">'Hello, World!'</span> <span style="color:#66d9ef">end</span> -</code></pre></div><p>無事 Hello, World! と出力されるようになった。</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#66d9ef">true</span> +</span></span><span style="display:flex;"><span>puts <span style="color:#e6db74">'Hello, World!'</span> <span style="color:#66d9ef">end</span> +</span></span></code></pre></div><p>無事 Hello, World! と出力されるようになった。</p> <h1 id="なぜ-then-や--や改行が必要か">なぜ <code>then</code> や <code>;</code> や改行が必要か</h1> <p>なぜ <code>then</code> や <code>;</code> や改行 (以下 「<code>then</code> 等」) が必要なのだろうか。次の例を見てほしい:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-ruby" data-lang="ruby"><span style="color:#66d9ef">if</span> a b <span style="color:#66d9ef">end</span> -</code></pre></div><p><code>then</code> も <code>;</code> も改行もないのでエラーになるが、これは条件式がどこまで続いているのかわからないためだ。 +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#66d9ef">if</span> a b <span style="color:#66d9ef">end</span> +</span></span></code></pre></div><p><code>then</code> も <code>;</code> も改行もないのでエラーになるが、これは条件式がどこまで続いているのかわからないためだ。 この例は二通りに解釈できる。</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-ruby" data-lang="ruby"><span style="color:#75715e"># a という変数かメソッドの評価結果が truthy なら b という変数かメソッドを評価</span> -<span style="color:#66d9ef">if</span> a <span style="color:#66d9ef">then</span> - b -<span style="color:#66d9ef">end</span> -</code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-ruby" data-lang="ruby"><span style="color:#75715e"># a というメソッドに b という変数かメソッドの評価結果を渡して呼び出し、</span> -<span style="color:#75715e"># その結果が truthy なら何もしない</span> -<span style="color:#66d9ef">if</span> a(b) <span style="color:#66d9ef">then</span> -<span style="color:#66d9ef">end</span> -</code></pre></div><p><code>then</code> 等はこの曖昧性を排除するためにあり、条件式は <code>if</code> から <code>then</code> 等までの間にある、ということを明確にする。 +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#75715e"># a という変数かメソッドの評価結果が truthy なら b という変数かメソッドを評価</span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> a <span style="color:#66d9ef">then</span> +</span></span><span style="display:flex;"><span> b +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span> +</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#75715e"># a というメソッドに b という変数かメソッドの評価結果を渡して呼び出し、</span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># その結果が truthy なら何もしない</span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> a(b) <span style="color:#66d9ef">then</span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span> +</span></span></code></pre></div><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> も同じ役割を持つ。</p> <p>Ruby の場合、プログラマーが書きやすいよう改行でもって <code>then</code> が代用できるので、ほとんどの場合 <code>then</code> は必要ない。</p> <h1 id="case---in-における-then"><code>case</code> - <code>in</code> における <code>then</code></h1> @@ -142,33 +142,33 @@ C系の <code>if</code> 後に来る <code>(</code>/<code>)</code> や、Python ; </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>、改行のいずれかである。</p> <p>これにより、<code>case</code> - <code>when</code> による従来の構文と同じように、<code>then</code> 等をパターンの後ろに挿入すればよいことがわかった。つまり次の3通りのいずれかになる:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-ruby" data-lang="ruby"><span style="color:#66d9ef">case</span> x -<span style="color:#66d9ef">in</span> <span style="color:#ae81ff">1</span> <span style="color:#66d9ef">then</span> a -<span style="color:#66d9ef">in</span> <span style="color:#ae81ff">2</span> <span style="color:#66d9ef">then</span> b -<span style="color:#66d9ef">in</span> <span style="color:#ae81ff">3</span> <span style="color:#66d9ef">then</span> c -<span style="color:#66d9ef">end</span> - -<span style="color:#66d9ef">case</span> x -<span style="color:#66d9ef">in</span> <span style="color:#ae81ff">1</span> - a -<span style="color:#66d9ef">in</span> <span style="color:#ae81ff">2</span> - b -<span style="color:#66d9ef">in</span> <span style="color:#ae81ff">3</span> - c -<span style="color:#66d9ef">end</span> - -<span style="color:#66d9ef">case</span> x -<span style="color:#66d9ef">in</span> <span style="color:#ae81ff">1</span>; a -<span style="color:#66d9ef">in</span> <span style="color:#ae81ff">2</span>; b -<span style="color:#66d9ef">in</span> <span style="color:#ae81ff">3</span>; c -<span style="color:#66d9ef">end</span> -</code></pre></div><p>ところで、<code>p_top_expr</code> には <code>if</code> による guard clause が書けるので、その場合は <code>if</code> - <code>then</code> と似たような見た目になる。</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-ruby" data-lang="ruby"><span style="color:#66d9ef">case</span> x -<span style="color:#66d9ef">in</span> <span style="color:#ae81ff">0</span> <span style="color:#66d9ef">then</span> a -<span style="color:#66d9ef">in</span> n <span style="color:#66d9ef">if</span> n <span style="color:#f92672"><</span> <span style="color:#ae81ff">0</span> <span style="color:#66d9ef">then</span> b -<span style="color:#66d9ef">in</span> n <span style="color:#66d9ef">then</span> c -<span style="color:#66d9ef">end</span> -</code></pre></div><h1 id="まとめ">まとめ</h1> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#66d9ef">case</span> x +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">in</span> <span style="color:#ae81ff">1</span> <span style="color:#66d9ef">then</span> a +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">in</span> <span style="color:#ae81ff">2</span> <span style="color:#66d9ef">then</span> b +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">in</span> <span style="color:#ae81ff">3</span> <span style="color:#66d9ef">then</span> c +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">case</span> x +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">in</span> <span style="color:#ae81ff">1</span> +</span></span><span style="display:flex;"><span> a +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">in</span> <span style="color:#ae81ff">2</span> +</span></span><span style="display:flex;"><span> b +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">in</span> <span style="color:#ae81ff">3</span> +</span></span><span style="display:flex;"><span> c +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">case</span> x +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">in</span> <span style="color:#ae81ff">1</span>; a +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">in</span> <span style="color:#ae81ff">2</span>; b +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">in</span> <span style="color:#ae81ff">3</span>; c +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span> +</span></span></code></pre></div><p>ところで、<code>p_top_expr</code> には <code>if</code> による guard clause が書けるので、その場合は <code>if</code> - <code>then</code> と似たような見た目になる。</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#66d9ef">case</span> x +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">in</span> <span style="color:#ae81ff">0</span> <span style="color:#66d9ef">then</span> a +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">in</span> n <span style="color:#66d9ef">if</span> n <span style="color:#f92672"><</span> <span style="color:#ae81ff">0</span> <span style="color:#66d9ef">then</span> b +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">in</span> n <span style="color:#66d9ef">then</span> c +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span> +</span></span></code></pre></div><h1 id="まとめ">まとめ</h1> <ul> <li><code>if</code> や <code>case</code> の条件の後ろには <code>then</code>、<code>;</code>、改行のいずれかが必要 <ul> |
