2004年08月06日
川俣晶の縁側ソフトウェアRuby&RPGツクールXPtotal 6191 count

これは凄いぞ、Rubyの条件修飾子はそのへんのプログラム言語には見られないものだが、素晴らしく意味はある!

Written By: 川俣 晶連絡先

 更に調子に乗って、今度は気になって仕方がない条件修飾子を使ってみます。

 こんなものを書いてみました。

(0..3).each {|i| 

  p "偶数" if (i & 1) == 0

  p "奇数" if (i & 1) != 0

}

exit

 実行させると偶数、奇数、偶数、奇数と4回のメッセージボックスが出ます。

これもクールだ、範囲式 §

 先に、もう1つの新ネタを説明しておくと、0..3は範囲式というものです。0から3までの数値の列を表現します。どうやら、単純に{0,1,2,3}というような配列に展開するわけではなく、始点と終点の情報のみを持つオブジェクト(Rangeクラス)として生成されるようです。これは効率が良さそう。しかも、ループ変数の代わりに使うと安全性も高そうですね。たとえば、C系言語でfor( int i=0; i<count; i++)のように書いたり、BASIC系言語でFor i=0 To count-1のように書いた場合、途中でループ変数を強制書き換えしてループ回数を狂わせることは容易です。しかし、範囲式とイテレータの組み合わせだと、回数の元になる情報は固定的に範囲オブジェクトから提供されるので、たとえば上のソースの変数iを強制的に書き換えてもループ回数は変化しません。

 実にゾクゾクしますね。

条件修飾子 §

 p "偶数" if (i & 1) == 0と書いた行は、p "偶数"というコードと、それが実行される条件を書いたif (i & 1) == 0という修飾子に別れます。C#などでは、if (i & 1) == 0 p "偶数"というような順番で書くことになるので、これだけ見ると順番が逆転しているように見えますが、単に順番を逆転したという話ではありません。

 これはifのような条件判断をプロブラム言語で実現する場合の悩ましい問題と関連があります。

 たとえば、C系言語の場合、ifによって条件を判定した結果実行される命令は1つです。if(条件) 命令、という感じです。複数の命令を実行させたい場合は、ブロックを導入しなければなりません。つまり、if(条件) { 命令1; 命令2; 命令3; }という感じです。Pascal系言語だと、{と}はBeginとEndという長ったらしキーワードになり、けっこうこれがうるさく感じられたりします。

 一方、VBでは、条件判断の結果、実行する命令は1つに限られません。(Thenの直後に命令を書かないとすれば)、以下のようになります。

If 条件 Then

  命令1

  命令2

  命令3

End If

 この2つの流儀を比較すると、1つのジレンマが見られます。まず、C/Pascal系言語の場合でいえば、実行する命令が1つしかないということはあまり多くなく、たいていは複数の命令を並べます。ということは、いちいちブロックの開始と終了を書くのはめんどくさい、と言うことになります。この愚痴に対して、VBは解答を示しています。VBはIfはブロックであると考えるので、Ifがそもそもブロックの開始の宣言を兼任します。ブロックの終了はEnd Ifで表現されます。これにより、ブロックの終了はあるものの、ブロックの開始に相当する文字列はソースコード上から消滅させられました。

 これで、めでたしめでたし、ハッピーエンド……かというとそうではありません。

 この方法では、実行する命令が1つの場合でも、End Ifを書かねばならないという別の面倒が発生するからです。VBでは、Thenのあとに直接命令を書くという方法で、End If抜きのIf文を書けますが、これは1行に特権的な意味を持たせているVBだからできることです。そうではない多くのプログラム言語では、VBのような荒技は使えません。

 ではどうしたら良いのか。

 RubyのifはVB方式の構文を採用しています。if 条件式 命令1 命令2 命令3 endのような構文になります。(本当はRubyでは命令ではなく式と呼ぶのだけれど。それはさておき……)。

 この構文を使うと、実行する命令が1つきりでもendを書く必要があって面倒くさくなります。

 では、命令が1つならendを書かなくて良いというルールを導入できるかというと、解釈が曖昧になってしまうのでできません。

 そこで意味を持つのが修飾子です。修飾子は、式を修飾するものであって、自分が主役になるものではありません。ifから始まる条件判断構文なら、常に最後にendを書くことが要求されるというルールを堅持した上で、式のあとにifを書いた場合は修飾子と見なすことで、1つの式にのみ適用され、endを書く必要はない条件判断を記述可能になります。

 おそらく、そのような問題について頭をひねったことがある人は多くなく、そもそもそのようなジレンマが存在するということに気付いてもいない人が大半だと思います。

 そんな状況で、まさにそれに対する1つのクールな答えを示しているRubyを見るのは、一種の感動とも言えますね。

 こういう素晴らしい感動は、なかなか味わえるものではありません。

 Rubyは実にクールで素晴らしい!

Facebook

キーワード【 川俣晶の縁側ソフトウェアRuby&RPGツクールXP
【Ruby&RPGツクールXP】の次のコンテンツ
2012年
10月
11日
久々に動かしたRPGツクールXP
3days 0 count
total 3034 count
【Ruby&RPGツクールXP】の前のコンテンツ
2004年
08月
06日
Rubyのイテレータを初体験 (C#、VB.NETとソース比較付き)
3days 0 count
total 3989 count

このコンテンツを書いた川俣 晶へメッセージを送る

[メッセージ送信フォームを利用する]

メッセージ送信フォームを利用することで、川俣 晶に対してメッセージを送ることができます。

この機能は、100%確実に川俣 晶へメッセージを伝達するものではなく、また、確実に川俣 晶よりの返事を得られるものではないことにご注意ください。

このコンテンツへトラックバックするためのURL

https://mag.autumn.org/tb.aspx/20040806232139
サイトの表紙【Ruby&RPGツクールXP】の表紙【Ruby&RPGツクールXP】のコンテンツ全リスト 【Ruby&RPGツクールXP】の入手全リスト 【Ruby&RPGツクールXP】のRSS1.0形式の情報このサイトの全キーワードリスト 印刷用ページ

管理者: 川俣 晶連絡先

Powered by MagSite2 Version 0.36 (Alpha-Test) Copyright (c) 2004-2021 Pie Dey.Co.,Ltd.