# Does case/when really use ===?

**URL:** <https://www.ruby-forum.com/t/does-case-when-really-use/71607>\
**Category:** Ruby\
**Created:** [October 10, 2006, 9:36am UTC](https://www.ruby-forum.com/t/does-case-when-really-use/71607 "2006-10-10T09:36:00Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![edenli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9e8a1a/32.png) [@edenli](https://www.ruby-forum.com/u/edenli)\
**Post date:** [October 10, 2006, 9:36am UTC](https://www.ruby-forum.com/t/does-case-when-really-use/71607/1 "2006-10-10T09:36:00Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![edenli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9e8a1a/32.png) [@edenli](https://www.ruby-forum.com/u/edenli)\
**Post date:** [October 10, 2006, 9:44am UTC](https://www.ruby-forum.com/t/does-case-when-really-use/71607/2 "2006-10-10T09:44:00Z")

</div>

On 10/10/06, eden li [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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

---

<div class="post-metadata">

**Author:** ![edenli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9e8a1a/32.png) [@edenli](https://www.ruby-forum.com/u/edenli)\
**Post date:** [October 10, 2006, 9:48am UTC](https://www.ruby-forum.com/t/does-case-when-really-use/71607/3 "2006-10-10T09:48:01Z")

</div>

case bla  
when Foo  
end

calls Foo === bla, not bla === Foo

---

<div class="post-metadata">

**Author:** ![edenli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9e8a1a/32.png) [@edenli](https://www.ruby-forum.com/u/edenli)\
**Post date:** [October 11, 2006, 5:12pm UTC](https://www.ruby-forum.com/t/does-case-when-really-use/71607/4 "2006-10-11T17:12:07Z")

</div>

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

> 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

---

<div class="post-metadata">

**Author:** ![edenli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9e8a1a/32.png) [@edenli](https://www.ruby-forum.com/u/edenli)\
**Post date:** [October 12, 2006, 10:20am UTC](https://www.ruby-forum.com/t/does-case-when-really-use/71607/5 "2006-10-12T10:20:49Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![edenli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9e8a1a/32.png) [@edenli](https://www.ruby-forum.com/u/edenli)\
**Post date:** [October 12, 2006, 12:58pm UTC](https://www.ruby-forum.com/t/does-case-when-really-use/71607/6 "2006-10-12T12:58:14Z")

</div>

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

> 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
