From: RichardOnRails Date: 2011-01-27T12:06:15+09:00 Subject: Re: Problem: use case stmt on object's class in simple test On Jan 26, 7:10 pm, "Aaron D. Gifford" wrote: > user@host:/path$ irb > irb(main):001:0> a = "Foo" > => "Foo" > irb(main):002:0> a.class === String > => false > irb(main):003:0> a === String > => false > irb(main):004:0> a.class === String.class > => false > irb(main):005:0> a > => "Foo" > irb(main):006:0> a.inspect > => "\"Foo\"" > irb(main):007:0> String.inspect > => "String" > irb(main):008:0> case a > irb(main):009:1> when String > irb(main):010:1> puts 'string' > irb(main):011:1> else > irb(main):012:1* puts 'not' > irb(main):013:1> end > string > => nil > irb(main):014:0> String === a > => true > irb(main):015:0> a === String > => false > irb(main):016:0> root@secure:/usr/ports# irb > irb(main):001:0> str = "a string" > => "a string" > irb(main):002:0> str.class > => String > irb(main):003:0> String === str.class > => false > irb(main):004:0> String === str > => true > irb(main):005:0> case str.class > irb(main):006:1> when String > irb(main):007:1>   puts 'it is a string' > irb(main):008:1> else > irb(main):009:1*   puts 'else executed' > irb(main):010:1> end > else executed > => nil > irb(main):011:0> case str > irb(main):012:1> when String > irb(main):013:1>   puts 'it is a string' > irb(main):014:1> else > irb(main):015:1*   puts 'else executed' > irb(main):016:1> end > it is a string > => nil > irb(main):017:0> > > >  Why isn't the "when String" statement executed? > > I believe case/when uses the when object's === method for matching, > and as you can see from the above irb session, String === "a > string".class evaluates to false.  Hence your code doesn't work like > you expected. > > However, if you change to hash[key] instead of hash[key].class, a > direct comparison to the class object should work (note the String === > "a string" evaluates to true). > > Note that "a string" === String evaluates to false even though "a > string" === String evaluates to true.  That way case String when "a > string" won't match but case "a string" when String will.  (Which > totally makes sense in the context of case/when.) > > I'm sure I read a great blog post or discussion on this very thing in > the past on the web, one that explains the gory details about exactly > why case/when was designed to work this way.  It currently slips my > mind. > > Anyone got a good URL for an article/post like that? > > Aaron out. Hey Aaron, You scored a triple. I should say you scored 3 homers. In order of importance on my grading scale: 1. You solved my problem: Lose the ".class" 2. You showed me that using IRB for experimenting like this is far better than littering one's code with debugging statements. 3. You reminded me to RTFM! Actually, I rotate between books, PDFs and blogs on Ruby, Rails, CSS, RSpec, etc. all the time. But as I encountered this unfathomable situation, I didn't do what I've now done: Consult PickAxe (2nd ed., 2005), which confirmed your belief that case uses === for a comparison of the case parameter and when arguments. Many thanks for your deep and insightful solution to my question. Best wishes, Richard