やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

「Ruby プログラムの実行」を読む1(文、式、ブロック、修飾子、演算子)

 公式ドキュメントの中身がすっからかん。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' }

 beginend式と、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

反転式

 「反転式」なんて名前の式はない。私が勝手に名付けた。unlessuntilのことを指す。これらはifwhileの反転系である。

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が書けない。真偽以外のときはifcaseを使うこと。

対象環境

$ uname -a
Linux raspberrypi 5.10.52-v7l+ #1441 SMP Tue Aug 3 18:11:56 BST 2021 armv7l GNU/Linux