Project

General

Profile

Actions

Feature #11737

closed

Pass in expression to then block in `case expression`

Added by danielpclark (Daniel P. Clark) almost 10 years ago. Updated almost 10 years ago.

Status:
Rejected
Assignee:
-
Target version:
-
[ruby-core:71664]

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) almost 10 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) almost 10 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) almost 10 years ago

It reminded me a rejected proposal:

case expr
when matcher => result
  ...
end

Updated by danielpclark (Daniel P. Clark) almost 10 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) almost 10 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) almost 10 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) almost 10 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) almost 10 years ago

Thank you. I appreciate your consideration.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0