Problem with case statements

I have an innocent looking code:

54: def find(*args)
55: options = args.extract_options!
56: validate_find_options(options)
57: case args.first
58: when :first: find_first(options)
59: when :all: find_all(options)
60: else raise “Invalid find”
61: end
62: end

Now, above case statement totally blows up with Ruby 1.9:

/home/hemant/push_server/lib/db_connection.rb:61: warning: else without
rescue is useless
/home/hemant/push_server/bin/boot.rb:34:in
require': /home/hemant/push_server/lib/db_connection.rb:58: syntax error, unexpected ':', expecting keyword_then or ',' or ';' or '\n' (SyntaxError) when :first: find_first(options) ^ /home/hemant/push_server/lib/db_connection.rb:59: syntax error, unexpected keyword_when, expecting keyword_end when :all: find_all(options) ^ /home/hemant/push_server/lib/db_connection.rb:87: syntax error, unexpected keyword_end, expecting $end from /home/hemant/push_server/bin/boot.rb:34:in<top (required)>’

However if i rewrite it like this, it works:

def find(*args)
  options = args.extract_options!
  validate_find_options(options)
  case args.first
  when :first
    find_first(options)
  when :all
    find_all(options)
  else
    raise "Invalid find"
  end
end

Why is this? Was this intended?

On Dec 21, 2007 12:14 PM, hemant kumar [email protected] wrote:

62: end

Now, above case statement totally blows up with Ruby 1.9:

My test is with Ruby 1.8.6 but:

/home/hemant/push_server/bin/boot.rb:34:in
`require’: /home/hemant/push_server/lib/db_connection.rb:58: syntax
error, unexpected ‘:’, expecting keyword_then or ‘,’ or ‘;’ or
‘\n’ (SyntaxError)
when :first: find_first(options)

if you want to put the body of the when in the same line you need a
then keyword:

irb(main):018:0> def find(*args)
irb(main):019:1> case args.first
irb(main):020:2> when :first then puts “first”
irb(main):021:2> when :all then puts “all”
irb(main):022:2> else raise “invalid”
irb(main):023:2> end
irb(main):024:1> end
=> nil
irb(main):025:0> find :first, 1, 2, 3, 4
first
=> nil

  else
    raise "Invalid find"
  end
end

Why is this? Was this intended?

From the pickaxe:

“The then keyword (or a colon) separates the when comparisons from the
bodies and is
not needed if the body starts on a new line.”

Hope this helps,

Jesus.

Jesús Gabriel y Galán wrote:

if you want to put the body of the when in the same line you need a
then keyword:

1.8.6 works with a keyword or a colon, I think this is what Hemant
means… 1.9 obviously doesn’t support using them (I can’t test it right
now)

def find(*args)
case args.first
when :first: puts “first”
when :all: puts “all”
else raise “invalid”
end
end
=> nil

find :first, 1, 2, 3, 4
first

As you can see, Hemants example works fine with colons in 1.8.6, perhaps
not in 1.9, though…

I normally use ‘then’ in either case…

Regards,
Lee

Jesús Gabriel y Galán wrote:

if you want to put the body of the when in the same line you need a
then keyword:

1.8.6 works with a keyword or a colon, I think this is what Hemant
means… 1.9 obviously doesn’t support using them (I can’t test it right
now)

def find(*args)
case args.first
when :first: puts “first”
when :all: puts “all”
else raise “invalid”
end
end
=> nil

find :first, 1, 2, 3, 4
first

As you can see, Hemants example works fine with colons in 1.8.6, perhaps
not in 1.9, though…

I normally use ‘then’ in either case…

Regards,
Lee

On Dec 21, 2007 12:48 PM, Lee J. [email protected] wrote:

when :first: puts “first”
not in 1.9, though…
I normally use ‘then’ in either case…

Oh, you are right, I missed the colon after the symbol. :frowning:
Sorry for the noise.

Jesus.

On Fri, 2007-12-21 at 21:01 +0900, Robert K. wrote:

61: end
‘\n’ (SyntaxError)
Does the same error surface if you precede the colon with a space?
when :all
find_all(options)
else
raise “Invalid find”
end
end

Why is this? Was this intended?

Maybe the form with colon is deprecated?

Looks like they deprecated “:” in case statements.

Matz, shall we consider this as bug or change was unintentional?

2007/12/21, hemant kumar [email protected]:

62: end
when :first: find_first(options)
^
/home/hemant/push_server/lib/db_connection.rb:59: syntax error,
unexpected keyword_when, expecting keyword_end
when :all: find_all(options)
^
/home/hemant/push_server/lib/db_connection.rb:87: syntax error,
unexpected keyword_end, expecting $end
from /home/hemant/push_server/bin/boot.rb:34:in `<top (required)>’

Does the same error surface if you precede the colon with a space?
Sorry, I don’t have a 1.9 here to test this myself.

  else
    raise "Invalid find"
  end
end

Why is this? Was this intended?

Maybe the form with colon is deprecated?

Kind regards

robert

Le 21 décembre à 14:18, hemant kumar a écrit :

My bad… i meant intentional, but you got the point anyways!.

According to the 3rd edition of the PickAxe, it is intentional.

(p 125, Case Expressions : “Ruby 1.8 allowed you to use a colon
character in place of the then keyword. This is no longer supported.”)

Fred

On Fri, 2007-12-21 at 18:47 +0530, hemant kumar wrote:

60: else raise “Invalid find”
error, unexpected ‘:’, expecting keyword_then or ‘,’ or ‘;’ or

    find_first(options)

Looks like they deprecated “:” in case statements.

Matz, shall we consider this as bug or change was unintentional?

My bad… i meant intentional, but you got the point anyways!.

Thanks

Looks like they deprecated “:” in case statements.
you can replace them with “;” or “then” to be Ruby 1.8 and 1.9
compatible. but it’s ugly. I prefer the colon variant.

can we have the colon back, matz? at least for “case”.
[murphy]

On Fri, 2007-12-21 at 22:55 +0900, F. Senault wrote:

Le 21 décembre à 14:18, hemant kumar a écrit :

My bad… i meant intentional, but you got the point anyways!.

According to the 3rd edition of the PickAxe, it is intentional.

(p 125, Case Expressions : “Ruby 1.8 allowed you to use a colon
character in place of the then keyword. This is no longer supported.”)

Ha ha… damn to its decided. I don’t own third edition apparently.

On Dec 21, 2007 9:01 AM, murphy [email protected] wrote:

Looks like they deprecated “:” in case statements.
you can replace them with “;” or “then” to be Ruby 1.8 and 1.9
compatible. but it’s ugly. I prefer the colon variant.

can we have the colon back, matz? at least for “case”.
[murphy]

I suspect that it’s gone because of a conflict with the new keyword
style hash literal syntax in 1.9.

On the other hand changing the colon to a semi-colon will work.

when :first; find_first(options)


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/