From: Michael Edgar Date: 2011-08-22T08:45:41+09:00 Subject: Re: Possble bug in Ruby parser (Fixnum#times within "case" statement) On Aug 21, 2011, at 7:12 PM, Iņaki Baz Castillo wrote: > Hi, I cannot find an explanation for the following issue so I think it's a bug: > > ----------------------- > def kk > > while case @state > > when :init > 10.times do |index| > puts "index = #{index}" > end > @state = :end > true > > when :end > puts "END" > > end > end > > end > > @state = :init > kk > ----------------------- > > > Running the above code gives an error: > > ~# ruby1.9.3 kk.rb > > kk.rb:6: syntax error, unexpected keyword_do_cond, expecting keyword_end > 10.times do |index| > ^ > kk.rb:7: syntax error, unexpected tSTRING_BEG, expecting keyword_do or > '{' or '(' > puts "index = #{index}" > ^ > kk.rb:12: syntax error, unexpected keyword_when, expecting $end > when :end > ^ > > > Why???? If I replace: > > 10.times do |index| > puts "index = #{index}" > end > > with: > > 10.times { |index| > puts "index = #{index}" > } > > but of course using "do - end" is valid for Fixnum#times !! > What is happening? "while" cannot take braces, only do-end. Your entire `case` expression is the clause of the while loop, so the "do" is begin confused for the "do" that optionally comes between the "while"'s condition and its body. Since a brace never comes between a while condition and a while body, there's no ambiguity. Ruby's grammar is expressive, but when you do things like put many-line case statements in a while condition, you're going to get weird corner cases in the grammar. Michael Edgar adgar@carboni.ca http://carboni.ca/