Use of case statement doesn't work as I expected, what am I doing wrong?

Hi all,

I have an object ( a website tester) that can return various values.
One of which is Net:HTTPOK, I want to use a case statement to evaluate
this and set a variable called ‘severity’, as follows:

result = TestWebsite::test( site )
case result
when Net::HTTPOK
severity = :INFO
when SocketError
severity = :ERROR
else
severity = :WARN
end

However, when Net::HTTPOK is returned, the severity variable ALWAYS
ends up as :WARN instead of :INFO.

Using IRB I have manually entered the code in as follows:

site = ‘beautyandthebrand.co.uk
=> “beautyandthebrand.co.uk

result = TestWebsite::test( site )
=> Net::HTTPOK

Then ran the following tests:

result == Net::HTTPOK
=> true

result != Net::HTTPOK
=> false

This to me just proves the result I am getting is Net::HTTPOK, but why
can’t I get it to match in the case statement?

Many thanks for any help

Gabriel

Hi –

On Fri, 2 Nov 2007, Gabriel D. wrote:

when SocketError
=> “beautyandthebrand.co.uk
I get it to match in the case statement?
The test that the case statement is running is this:

Net::HTTPOK === result # note the order, and the 3 equal signs

I don’t know exactly what Net::HTTPOK is, or how it handles ===, but
evidentally it doesn’t consider itself “threequal” to result.

David

On Nov 1, 2007, at 12:36 PM, Gabriel D. wrote:

else
severity = :WARN
end

However, when Net::HTTPOK is returned, the severity variable ALWAYS
ends up as :WARN instead of :INFO.

There are two issues:

  1. case uses the === operator and not ==

This means that the comparisons in your case statement are:

Net::HTTPOK === result
SocketError === result

  1. Class#=== doesn’t test for equality. It checks to see if
    the argument is an instance of the class, which is not
    true in your case, Net::HTTPOK is not an instance of itself.

Just to be clear, Net::HTTPOK and SocketError are class objects
(instances of Class) and so they use Class#=== in case statements.

You could rewrite your case as an if/then/else or use the alternate
form of the case statement:

case
when result == Net::HTTPOK
severity = :INFO
when result == SocketError
severity = :ERROR
else
severity = :WARN
end

There of course lots of other possibilities:

severity_map = Hash.new(:WARN).merge(Net::HTTPOK => :INFO,
SocketError => :ERROR)

severity = severity_map[TestWebsite::test(site)]

Gary W.