Case equality question

Hello

I do not understand the following code:

···

======
file = File.open('test.txt', 'r')
hash = {'file' => file, 'title' => 'title'}
hash.map { | param_key, param_value |
   puts "param_key = #{param_key}"
   puts "param_value = #{param_value}"
   puts "(param_value === String) = #{(param_value === String)}"
   case param_value
     when String
       puts "This is a String!"
     when File
       puts "This is a File!"
     else
       puts "Neither String nor File!!!"
   end
}
file.close

When I run this code the output is as follows:
param_key = title
param_value = title
(param_value === String) = false
This is a String!
param_key = file
param_value = #<File:0x2b689b8>
(param_value === String) = false
This is a File!

Why does Ruby goes to the when String case even if (param_value === String) is false?

BR Phil

Why does Ruby goes to the when String case even if (param_value ===
String) is false?

I've been very suprised with this recently, but...

'a' === String

=> false

1 === String

=> false

String === 'a'

=> true

String === 1

=> false

Fred

···

Le 24 juillet 2007 à 11:55, Phil Meier a écrit :
--
It's a hard work, being a network pusher. Your customers beep you in
the middle of the night, hungry for another fix. But, what can you do ?
Customer satisfaction and all that crap...
Pays good, though. (Ingvar the Grey in the SDM)

Phil Meier wrote:

Why does Ruby goes to the when String case even if (param_value ===
String) is false?

Because it checks whether String===param_value and not param_value===String.

HTH,
Sebastian Hungerecker.

···

--
NP: Green Carnation - When I Was You
Ist so, weil ist so
Bleibt so, weil war so

Hi --

Hello

I do not understand the following code:

======
file = File.open('test.txt', 'r')
hash = {'file' => file, 'title' => 'title'}
hash.map { | param_key, param_value |
puts "param_key = #{param_key}"
puts "param_value = #{param_value}"
puts "(param_value === String) = #{(param_value === String)}"
case param_value
   when String
     puts "This is a String!"
   when File
     puts "This is a File!"
   else
     puts "Neither String nor File!!!"
end
}
file.close

When I run this code the output is as follows:
param_key = title
param_value = title
(param_value === String) = false
This is a String!
param_key = file
param_value = #<File:0x2b689b8>
(param_value === String) = false
This is a File!

Why does Ruby goes to the when String case even if (param_value === String) is false?

Because String === param_value is true :slight_smile: That's how the case thing
works:

   obj = Object.new
   def obj.===(other)
     puts "I'm being cased!"
     true
   end

   case "blah"
     when obj
   end

Output:

   I'm being cased!

because obj === "blah" is being called.

David

···

On Tue, 24 Jul 2007, Phil Meier wrote:

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

Hm...I'm not sure I like that it doesn't go the other way. I like it
when code is easily converted to plain speech, when a line can be read
across quickly. And this seems to break that. Maybe not, but here's
how I see it:

b === a checks if a is-a b, right? Well isn't it a lot easier to read/
write/say "A is a B" than "B is instantiated in A" or "An example of B
is A"? Maybe this is a semantic quibble, but since English speakers
(and consequently a majority of the programming community) read left
to right, wouldn't it make more sense to have it behave this way?

It wouldn't even necessarily break case statements, since the .===
method would be part of all of the basic type classes (Fixnum/String/
etc) and there's always .class

This is just my opinion, and I admit to not knowing a lot yet. But I
figured I'd voice my thoughts.

Hi --

Why does Ruby goes to the when String case even if (param_value ===
String) is false?

I've been very suprised with this recently, but...

'a' === String

=> false

1 === String

=> false

String === 'a'

=> true

String === 1

=> false

Don't be surprised -- it would be very weird the other way. You'd
have to do:

   case String
   when "abc"

and so forth. It wouldn't really be useable as the basis of a case
structure.

David

···

On Tue, 24 Jul 2007, F. Senault wrote:

Le 24 juillet 2007 à 11:55, Phil Meier a écrit :

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

case some_obj
when String
   # do String stuff with some_obj
when 50..100
   # do number stuff with some_obj
end

Perhaps you just need to think of different language when you want to "read" the code:

"When String recognized some_obj, do String stuff with some_obj; when the range 50 to 100 recognizes some_obj, do number stuff with some_obj."

The way in which Class constants (like String or Fixnum) recognize (apply ===) happens to be an "is a?" test is happy arrangement.

You could even go further and read that as:

"Focus on some_obj and when String recognizes it, ..."

To distinguish the "case expr when obj" from the "case when expr" form that is much closer to an "if-elsif-else" construct.

-Rob

Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

···

On Jul 24, 2007, at 10:00 AM, Kaldrenon wrote:

Hm...I'm not sure I like that it doesn't go the other way. I like it
when code is easily converted to plain speech, when a line can be read
across quickly. And this seems to break that. Maybe not, but here's
how I see it:

b === a checks if a is-a b, right? Well isn't it a lot easier to read/
write/say "A is a B" than "B is instantiated in A" or "An example of B
is A"? Maybe this is a semantic quibble, but since English speakers
(and consequently a majority of the programming community) read left
to right, wouldn't it make more sense to have it behave this way?

It wouldn't even necessarily break case statements, since the .===
method would be part of all of the basic type classes (Fixnum/String/
etc) and there's always .class

This is just my opinion, and I admit to not knowing a lot yet. But I
figured I'd voice my thoughts.

Kaldrenon wrote:

Hm...I'm not sure I like that it doesn't go the other way.

Wouldn't work.

b === a checks if a is-a b, right?

Only if b is a class. If b is e.g. a range or an array, it checks whether b
includes a. If b is a regex it checks whether b matches a. For many other
things it's just the same as b==a.

It wouldn't even necessarily break case statements, since the .===
method would be part of all of the basic type classes (Fixnum/String/
etc) and there's always .class

There's always .class, but that doesn't help you unless you assume that the
argument passed to === will always be a class, which it won't.

···

--
NP: Explosions in the Sky - Magic Hours
Ist so, weil ist so
Bleibt so, weil war so

Okay, that's a more logical way of thinking about it, thank you. See,
I was looking at === as equivalent to Java's instanceof keyword, but I
can see now that that's not all === does.

Thanks for helping me clear it up.

···

On Jul 24, 10:28 am, Sebastian Hungerecker <sep...@googlemail.com> wrote:

Only if b is a class. If b is e.g. a range or an array, it checks whether b
includes a. If b is a regex it checks whether b matches a. For many other
things it's just the same as b==a.

Hi --

Only if b is a class. If b is e.g. a range or an array, it checks whether b
includes a. If b is a regex it checks whether b matches a. For many other
things it's just the same as b==a.

Okay, that's a more logical way of thinking about it, thank you. See,
I was looking at === as equivalent to Java's instanceof keyword, but I
can see now that that's not all === does.

=== is a method, so its behavior is completely programmable per class
or per object. That's why you get things like:

  /abc/ === "abcdef" # true

One fairly generalized way to read a === b is: a is the case of b.
You might need to embellish it a bit, but it gives you a start:

   (matching) /abc/ is the case of "abcdef"
   (being an instance of) String is the case of "abc"

etc.

David

···

On Tue, 24 Jul 2007, Kaldrenon wrote:

On Jul 24, 10:28 am, Sebastian Hungerecker <sep...@googlemail.com> > wrote:

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)