Feature #11737
closedPass in expression to then block in `case expression`
Description
Ruby's case <expression>
scenario allows the expression to be tested in the when
test with :===
, but in the then block the expression is not accessible. Only if the expression has been assigned to a variable beforehand can it be checked.
case 4
when ->i{ puts :when; true}
->i{ puts i}
else
:foo
end
# when
# => #<Proc:0x00000000d91e58@(irb):16 (lambda)>
case 4
when ->i{ puts :when; true}
puts _
else
:foo
end
# when
# #<Proc:0x00000000d91e58@(irb):16 (lambda)>
# => nil
case 4
when 4
then _
end
# => nil
case 4
when 4
then ->i{puts i}
end
# => #<Proc:0x000000015f9be0@(irb):36 (lambda)>
If some one wanted to give an expression after case that wasn't assigned to a variable then there is no access to it in the then block.
I suggest assigning the expression to the _
variable during a case/when/then scenario. Here's a rather contrived example use case.
case Enumerator.new do |y| y << 1; y << 2; y << 3; end
when ->e{ 2.times e.next; true}
then _.peek
end == 3
Updated by danielpclark (Daniel P. Clark) over 8 years ago
Please fix the when scenario in the last example
case Enumerator.new do |y| y << 1; y << 2; y << 3; end
when ->e{ 2.times{e.next}; true}
then _.peek
end == 3
Updated by danielpclark (Daniel P. Clark) over 8 years ago
Since https://bugs.ruby-lang.org/issues/11734#note-3 has informed me the _
is an IRB feature and Minitest uses _()
in its test suite perhaps we should not use _
for the case/when/then.
How about __case__
case Enumerator.new do |y| y << 1; y << 2; y << 3; end
when ->e{ 2.times{e.next}; true}
then __case__.peek
end == 3
Updated by nobu (Nobuyoshi Nakada) over 8 years ago
It reminded me a rejected proposal:
case expr
when matcher => result
...
end
Updated by danielpclark (Daniel P. Clark) over 8 years ago
Nobuyoshi Nakada wrote:
It reminded me a rejected proposal:
case expr when matcher => result ... end
I don't think so. It's not too different from what already works if you create a variable beforehand.
e = Enumerator.new do |y| y << 1; y << 2; y << 3; end
case e
when ->x{ 2.times{x.next}; true}
then e.peek
end == 3
# => true
I just found it odd that in the when clause I can use a proc to grab the current case item, but in the then block there is nothing to check unless a variable has already been assigned.
Updated by wanabe (_ wanabe) over 8 years ago
Nobuyoshi Nakada wrote:
It reminded me a rejected proposal:
case expr when matcher => result ... end
Is the proposal [ ruby-dev:17615 ] ?
Or other?
Updated by danielpclark (Daniel P. Clark) over 8 years ago
case 4 # __case__ = 4
when 4 # 4 === __case__
puts "Success! #{__case__} is what we wanted!" # __case__ not defined! ... where did it go?
end
Updated by matz (Yukihiro Matsumoto) over 8 years ago
- Status changed from Open to Rejected
It's not worth adding special expression or variable for retrieving the when value.
Just use assignment.
Matz.
Updated by danielpclark (Daniel P. Clark) over 8 years ago
Thank you. I appreciate your consideration.