Crystal: case statement trailing comma bug

Created on 12 Oct 2019  路  8Comments  路  Source: crystal-lang/crystal

Trailing commas cause odd behavior matching everything except the match value.

ary = [1, 2, 3]

ary.each do |n|
  case n
  when 1
    puts "one #{n}"
  when 2,
    puts "two #{n}"
  end
end

Output:

one 1
two 3

Expected

one 1
two 2

Flipping case1 and case2 makes the output stranger.

two 1
one 1
two 3
Crystal 0.30.0 (2019-08-05)

LLVM: 8.0.0
Default target: x86_64-apple-macosx

All 8 comments

a comma means another expression to test against.
This is not a bug, just a bad edge case. I don't know how to improve it.

To be clear: Properly formatted the code looks like this:

ary = [1, 2, 3]

ary.each do |n|
  case n
  when 1
    puts "one #{n}"
  when 2, puts "two #{n}"
  end
end

This should explain the "strange" behaviour. There is no way to tell whether a trailing comma in a case expression might be a mistake or not.

Actually, we. could maybe disallow a newline after a comma in this case. The problem then becomes how to include many expressions that would look bad in a single line... but I'm open for suggestions!

(I say this because I was bitten by this too)

Maybe forcing a \ at the end of the line:

  case n
  when 1
    puts "one #{n}"
  when 2, \
    3
    puts "two #{n}"
  end

Or require parenthesis:

  case n
  when 1
    puts "one #{n}"
  when (2,
        3,
        4)
    puts "two #{n}"
  end

It's easy to know what the when condition includes.

FYI, Ruby requires () for method calls with arguments in when.

case 1
when 2,
  puts "string"
end
-:3: syntax error, unexpected tSTRING_BEG, expecting do or '{' or '('
  puts "string"

@lugia-kun That's an interesting fact. But won't make a difference for this issue anyway.

Was this page helpful?
0 / 5 - 0 ratings