case equality question

P

Phil Meier

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
 
F

F. Senault

Le 24 juillet 2007 à 11:55, Phil Meier a écrit :
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...
=> false
=> false

Fred
 
S

Sebastian Hungerecker

Phil said:
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.
 
D

dblack

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 :) 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

--
* 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)
 
D

dblack

---2049402039-636883661-1185271902=:1534
Content-Type: MULTIPART/MIXED; BOUNDARY="-2049402039-636883661-1185271902=:1534"

This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

---2049402039-636883661-1185271902=:1534
Content-Type: TEXT/PLAIN; charset=X-UNKNOWN; format=flowed
Content-Transfer-Encoding: QUOTED-PRINTABLE

Hi --

Le 24 juillet 2007 =E0 11:55, Phil Meier a =E9crit :


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

=3D> false

=3D> 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

--=20
* 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)
---2049402039-636883661-1185271902=:1534--
---2049402039-636883661-1185271902=:1534--
 
K

Kaldrenon

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.
 
R

Rob Biedenharn

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.

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
(e-mail address removed)
 
S

Sebastian Hungerecker

Kaldrenon said:
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.
 
K

Kaldrenon

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.

Thanks for helping me clear it up.
 
D

dblack

Hi --

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

--
* 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)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top