公式ドキュメントの中身がすっからかん。ggrksと言われている気分。
成果物
情報源
Ruby プログラムの実行
Ruby プログラムの実行は文の連なりの評価です。なんらかの形であたえられたプログラムテキストをコンパイルし、BEGIN 文があればそれを評価し、トップレベルの式の連なりを評価し、END ブロックがあれば最後にそれを評価して終了します (終了処理の詳細については 終了処理 を参照のこと)。
あれ、たしか前に「Rubyは文と式の違いがない」「すべて戻り値があるため、文にみえるものでも事実上、すべて式である」みたいなことが書いてあったような気がするんだが。その証拠に以下のように書けます、みたいなのどっかで見たぞ。
x = if true 'A' else 'B' end
「文」「式」「ブロック」。この3つの違いがわからん。ていうか、ブロックって{}
で囲まれた無名関数のことじゃなかったっけ? なんだよENDブロック
って。コード書いてくれよ。わかんねーよ。
たぶん文脈からして以下のいずれかのことを言っているのだろう。1番目のコードだと、今までの用語の意味と違う。2番目のコードなら、END
という名前付きブロックであると解釈できる。
BEGIN p 'START' END #<= こいつのことをENDブロックって言ってる?
BEGIN { p 'START' } END { p 'END' } #<= こいつのことをENDブロックって言ってる?
公式ドキュメントにはコードもなく説明もないのでさっぱりわからなかった。なのでググった。それによると上記一番目のコードはエラーになる。正しくは以下。
begin p 'START' end
BEGIN { p 'START' } END { p 'END' }
begin
〜end
式と、BEGIN
/END
ブロック文は別物。
なんて紛らわしいんだ。文、式、ブロックの用語すら定義されず曖昧なのに、さらに大文字/小文字によって別の構文である。こんなの、説明もコード例もなしにわかるわけないだろ!
もういいや。とにかく一旦このドキュメントの表現に従って始めよう。理解も納得もできていないけど。
文
if
if
修飾子unless
unless
修飾子while
while
修飾子until
until
修飾子for
begin
...end
- クラス定義式
- モジュール定義式
- 特異クラス定義式
- メソッド定義式
- 特異メソッド定義式
BEGIN
END
ドキュメントにはなぜかuntil
が2回出ている。たぶん正しくはunless
だと思う。誤記だろう。
あとさあ、見出しが「文」なのに項目には「修飾子」だの「式」だのって書いているんですけど? やっぱり超テキトーなんじゃないの? このドキュメント。すごい嫌になってきた。
なんちゃら定義式って、明らかにブロック文に見える。たしかほかの言語では複数行によって定義される文をブロック文と呼んでいたはず。でもRubyにはブロックという名前で無名関数を示しているから紛らわしい。だからここで急に「式」って言葉を使っているんじゃないだろうか。
でもほかのプログラミング言語では「式」というと計算式などを指す。1 + 2
とか。結果が戻り値として返るし、演算子もあったりする。それが式のはず。ほかの言語の常識でいってもわけがわからなくなるだけか。でもだからといって、Rubyの「文」「式」「ブロック」の用語の意味がちゃんと示されたわけじゃない。書いてくれよ。示してくれよ。適当に使ってんじゃないだろうな?
制御なら分岐とか繰り返しとかの分別もつけてほしかった。
もう私が勝手に分類しちゃう。
- 修飾子
- 制御修飾子
- 条件分岐修飾子
if
/unless
修飾子
- 繰り返し修飾子
while
/until
修飾子
- 条件分岐修飾子
- 制御修飾子
- 演算子
- 三項演算子:
(条件式) ? 真時の値 : 偽時の値\
- 三項演算子:
- 式
- 制御式
- 条件分岐式
if
/unless
case
- パターンマッチ
case
-in
- 繰り返し式
for
while
/until
- 条件分岐式
- 制御式
- ブロック文
- クラス定義式
- モジュール定義式
- 特異クラス定義式
- メソッド定義式
- 特異メソッド定義式
begin
/end
BEGIN
END
反転式
「反転式」なんて名前の式はない。私が勝手に名付けた。unless
やuntil
のことを指す。これらはif
やwhile
の反転系である。
真 | 偽 |
---|---|
if |
unless |
while |
until |
以下は同じである。
p 'T' if true p 'T' unless false
x = if true 'A' else 'B' end
=> "A"
x = unless true 'B' else 'A' end
=> "A"
while true p 'WHILE' break end
until false p 'UNTIL' break end
ようするに条件式の真偽値が反転した式である。if
は条件式が真のときに使う。対してuntil
は条件式が偽のときに使う。while
は条件式が真のとき繰り返す。until
は条件式が偽のとき繰り返す。
ほかのプログラミング言語だと、if not 条件式
、if !条件式
のように反転させて判定していたと思う。
if path.is_exist: ... # ファイルが存在している if not path.is_exist: ... # ファイルが存在していない
Rubyだと以下のように書く。
... if path.is_exist # ファイルが存在している ... unless path.is_exist # ファイルが存在していない
ただしunless
ではelsif
が書けない。真偽以外のときはif
かcase
を使うこと。
対象環境
- Raspbierry pi 4 Model B
- Raspberry Pi OS buster 10.0 2020-08-20 ※
- bash 5.0.3(1)-release
- Ruby 3.0.2
$ uname -a Linux raspberrypi 5.10.52-v7l+ #1441 SMP Tue Aug 3 18:11:56 BST 2021 armv7l GNU/Linux