Feature #15722
closed`Kernel#case?`
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) almost 6 years 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) almost 6 years ago
osyo (manga osyo) wrote:
How about
Enumerable#case?
?
Comparing with===
likeEnumerable#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) almost 6 years 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) almost 6 years 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.
Updated by osyo (manga osyo) almost 5 years 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) almost 5 years 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.
Updated by nobu (Nobuyoshi Nakada) almost 5 years ago
osyo (manga osyo) wrote in #note-6:
I think this is closer to the syntax of
case when
.
And what about adding a onelinewhen
like a onelinein
?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
As a case expr
statement doesn't need a terminator (newline or semicolon) before when
, it conflicts with the current syntax.