LoginSignup
1
1

More than 5 years have passed since last update.

Rubyで begin ... end と ( ... ) にwhile修飾子を適用したときの違い

Last updated at Posted at 2019-04-26

begin ... end(...) は例外処理の可否を除いて同じ動作だと思っていたが違った。

きっかけは、C言語でいう do { ... } while(0); (ブロックを1回だけ実行)をRubyで試したこと。

puts "example 1" while false

(
    puts "example 2"
) while false

begin
    puts "example 3"
end while false
output
example 3

Rubyにおいては例1,2の動作が自然だと思っていたので、C言語の例のようなことはできないと思っていたが、例3の通り begin ... end なら問題なく中身が実行された。

文法の仕様確認

JIS X 3017 を確認してみたところ、意外なことに処理系定義だった。

12.5 while 修飾文

構文規則
《while修飾文》 ::
     《文》 [《行終端子》禁止] “while” 《式》

意味規則
  S “while” E という形式の《while 修飾文》(ここで,S は《文》,E は《式》とする。)は,次の手順で評価する。
a) S が《begin 式》の場合,動作は処理系定義とする。
b) “while” E “do” S “end” という形式の《while 式》を評価する。
c) 評価結果の値を,《while 修飾文》の値とする。

処理系定義の場合は動作をドキュメントに書かなければならないらしい。Rubyリファレンスマニュアルを見たら、確かに明記されていた。

while 修飾子

例:

sleep(60) while io_not_ready?

文法:

 while 

右辺の式を評価した値が真の間、左辺を繰り返し実行します。

左辺の式が begin 節である場合にはそれを最初に一回評価してから繰り返します。

例:

send_request(data)
begin
  res = get_response()
end while res == 'Continue'

while 修飾した式は nil を返します。 また、引数を伴った break により while 修飾した式の戻り値をその値にすることもできます。

他の場合

仕様を見たら明らかだが、

  • until修飾子も begin ... end に対しては処理系定義
  • if修飾子、unless修飾子は特別扱いなし(これは当然だろう)
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1