[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Does case/when really use ===?

eden li

10/10/2006 7:35:00 AM

Can someone explain why my class's === method is never called in the
following code?

irb(main):001:0> class C; def ===(k); puts "===(#{k.inspect}) called";
true; end; end
=> nil
irb(main):002:0> case C.new; when String; 'is a String'; else; 'not a
String'; end
=> "not a String"

I expected "===(String) called" to be printed out somewhere, somewhat
like:

irb(main):003:0> C.new === String
===(String) called
=> true

Am I misunderstanding how case/when works?


5 Answers

Farrel Lifson

10/10/2006 7:43:00 AM

0

On 10/10/06, eden li <eden.li@gmail.com> wrote:
> Can someone explain why my class's === method is never called in the
> following code?
>
> irb(main):001:0> class C; def ===(k); puts "===(#{k.inspect}) called";
> true; end; end
> => nil
> irb(main):002:0> case C.new; when String; 'is a String'; else; 'not a
> String'; end
> => "not a String"
>
> I expected "===(String) called" to be printed out somewhere, somewhat
> like:
>
> irb(main):003:0> C.new === String
> ===(String) called
> => true
>
> Am I misunderstanding how case/when works?
>
>
>

In case statements such as
case(object)
when otherObject
puts "Match!"
else
puts "No match"
end

The === is not called on object but rather on otherObject.

Farrel

Sylvain Joyeux

10/10/2006 7:46:00 AM

0

case bla
when Foo
end

calls Foo === bla, not bla === Foo
--
Sylvain Joyeux

Ken Bloom

10/11/2006 3:07:00 PM

0

On Tue, 10 Oct 2006 16:34:52 +0900, eden li wrote:

> Can someone explain why my class's === method is never called in the
> following code?
>
> irb(main):001:0> class C; def ===(k); puts "===(#{k.inspect}) called";
> true; end; end
> => nil
> irb(main):002:0> case C.new; when String; 'is a String'; else; 'not a
> String'; end
> => "not a String"
>
> I expected "===(String) called" to be printed out somewhere, somewhat
> like:
>
> irb(main):003:0> C.new === String
> ===(String) called
> => true
>
> Am I misunderstanding how case/when works?

=== is not commutative (nor is it intended to be), and it actually gets
called in the other direction (the call it makes is String === C.new)

To test how this works:

class Class
alias_method :old_case_equals, :===
def ===(other)
puts "In Class.===: #{inspect}===#{other.inspect}"
old_case_equals(other)
end
end


be forewarned that doing something like this in IRB will cause very wierd
output, since irb uses this method internally.

--Ken

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...
I've added a signing subkey to my GPG key. Please update your keyring.

eden li

10/12/2006 8:15:00 AM

0

Got it.

This question came up because I was dealing with a library that has
wrapped a proxy class around an Array that intercepted methods to make
it appear as if that class is actually an Array class (rails'
AssociationProxy for those counting). Because I'm not native in Ruby,
I spent a good deal of time debugging a particular case/when statement.

This proxy class undefines all non-critical instance method (ie, ones
that Ruby does not throw an error for when you call undef_method on
them) and passes them to an internal instance variable on
method_missing. This makes it seem like an object of this proxy class
look like an instance of its internal variable, but only until you pass
it to the case/when construct.

This makes me wonder how the proxy class could be rewritten to make
case/when operate on that internal variable.

Is rewriting the Class.=== method to special-case the proxy class the
only way to accomplish this?

Ken Bloom wrote:
> === is not commutative (nor is it intended to be), and it actually gets
> called in the other direction (the call it makes is String === C.new)

Xavier Noria

10/12/2006 10:57:00 AM

0

On Oct 12, 2006, at 10:20 AM, eden li wrote:

> This question came up because I was dealing with a library that has
> wrapped a proxy class around an Array that intercepted methods to make
> it appear as if that class is actually an Array class (rails'
> AssociationProxy for those counting). Because I'm not native in Ruby,
> I spent a good deal of time debugging a particular case/when
> statement.
>
> This proxy class undefines all non-critical instance method (ie, ones
> that Ruby does not throw an error for when you call undef_method on
> them) and passes them to an internal instance variable on
> method_missing. This makes it seem like an object of this proxy class
> look like an instance of its internal variable, but only until you
> pass
> it to the case/when construct.
>
> This makes me wonder how the proxy class could be rewritten to make
> case/when operate on that internal variable.

In fact, why not just subclass Array?

Which is the benefit of pretending to be an Array to the point that
AssociationProxy#class returns Array? People get confused with a
different find/select in those "arrays", case/when behaves
unexpectedly, ..., is there some technical reason a subclass wouldn't
work or would have other sort of drawbacks that weight more?

-- fxn