Project

General

Profile

Feature #15722

`Kernel#case?`

Added by sawa (Tsuyoshi Sawada) 11 months ago. Updated 2 days ago.

Status:
Feedback
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:91924]

Description

I often want to use === to match a single object on the right side against multiple objects on the left, as is used in case-constructions, just to return a truth value, and end up writing like this:

bar # => "bar"
flag1 = case bar; when "foo", "bar", "baz"; true; end # => true
flag2 = case bar; when Symbol, String; true; end # => true

I propose Kernel#case? that should work like this:

bar # => "bar"
bar.case?("foo", "bar", "baz") # => true
bar.case?("qux") # => false
bar.case?(Symbol, String) # => true
bar.case?(Array) # => false
bar.case? # => false

It is similar to Rails' in?, but it differs from it in that it uses === for comparison, not ==.

Or, alternatively, allowing Kernel#instance_of? and Kernel#kind_of? to allow multiple arguments may be a compromise.

Updated by osyo (manga osyo) 11 months ago

How about Enumerable#case? ?
Comparing with === like Enumerable#include?.

bar # => "bar"
["foo", "bar", "baz"].case? bar # => true
["qux"].case? bar               # => false
[Symbol, String].case? bar      # => true
[Array].case? bar               # => false

Updated by sawa (Tsuyoshi Sawada) 11 months ago

osyo (manga osyo) wrote:

How about Enumerable#case? ?
Comparing with === like Enumerable#include?.

bar # => "bar"
["foo", "bar", "baz"].case? bar # => true
["qux"].case? bar               # => false
[Symbol, String].case? bar      # => true
[Array].case? bar               # => false

What is to be evaluated is bar, not the objects that you put in the arrays. bar has to be the receiver. That also matches with how case-construction works. Furthermore, having an array as in your proposal requires additional array to be created, which will be immediately disposed.

Updated by sawa (Tsuyoshi Sawada) 11 months ago

If such method, if any, should be rather defined on Object, that would be fine. I was not sure whether I should have requested this for Kernel or for Object.

Updated by shevegen (Robert A. Heiler) 11 months ago

This is an interesting idea. I have not thought through all implications but not withholding
that, I like it so +1 from me. I think matz has to decide whether this may be useful. Since
I love case/when in ruby in general, any extension, even secondary ideas, seem useful to me. :)
Although I have to admit, I am not sure if I yet had a use case as suggested by sawa, but I
still think it is a good idea.

I think whether it is on Kernel or Object or Enumerable is not the primary concern (that can
be decided anyway) - if matz is too busy right now then perhaps this could be suggested for
the next developer meeting to get more feedback.

I did not know about Rails in?, but I do not like the name "in?". I have no problem with
"case?".

One possible question from the core team might be whether the use case is sufficient (for
many ruby users). I can not answer that myself, to be honest, if that question would come
up - but I still like the idea.

PS: I almost overlooked the comment by osyo; I agree, that is a different suggestion so
I was confused for a moment. The original suggestion by sawa is clearer IMO and more
appropriate (to the proposed suggestion); wording it like:

["foo", "bar", "baz"].case? bar 

would be different, and is actually a bit confusing to me. So it should best be ignored;
sawa's original description is clearer and makes more sense to me, but this is just an
aside - I only was confused for a moment when I read the second code part by osyo.

#5

Updated by sawa (Tsuyoshi Sawada) 25 days ago

  • Description updated (diff)

Updated by osyo (manga osyo) 2 days ago

What about using #when? instead of #case??

bar # => "bar"
flag1 = case bar; when "foo", "bar", "baz"; true; end # => true
flag2 = case bar; when Symbol, String; true; end # => true

# Proposal by sawa
flag1 = bar.case? "foo", "bar", "baz" # => true
flag2 = bar.case? Symbol, String # => true

# Proposal by osyo
flag1 = bar.when? "foo", "bar", "baz" # => true
flag2 = bar.when? Symbol, String # => true

I think this is closer to the syntax of case when.
And what about adding a oneline when like a oneline in ?

bar # => "bar"
flag1 = case bar; when "foo", "bar", "baz"; true; end # => true
flag2 = case bar; when Symbol, String; true; end # => true

flag1 = bar when "foo", "bar", "baz" # => true
flag2 = bar when Symbol, String # => true

Updated by matz (Yukihiro Matsumoto) 2 days ago

  • Status changed from Open to Feedback

It is not obvious to me that #case? is useful. We need a real-world use-case.

  • I don't like the name case?
  • IMO, just use case statement

Matz.

Also available in: Atom PDF