From: Robert Klemme Date: 2007-05-27T18:10:02+09:00 Subject: Re: Tricky problem with === On 27.05.2007 07:04, Morton Goldberg wrote: > On May 26, 2007, at 11:13 PM, Erwin Abbott wrote: > >> I have a "BlankState" type of class and it's method_missing forwards >> everything to an instance variable. This way I can treat the object >> specially in my own code and all other code doesn't need to know the >> difference. For a contrived example: >> >> class Proxy >> # remove methods inherited by Object, etc >> instance_methods.each do |m| >> undef_method m unless m =~ /^__/ >> end >> >> def initialize name, value >> @name, @value = name, value >> end >> >> def to_myformat >> "#{@name}: #{@value}" >> end >> >> def method_missing name, *args, &block >> @value.send name, *args, &block >> end >> end >> >> object = "regular string" >> x = Proxy.new("UID", object) Erwin, are you aware of delegate? >> x.class # => Array >> x.size # => 5 >> x.to_myformat # => UID: regular string > > What I see when I evaluate your code is: > > x.class # => String > x.size # => 14 > >> While that's a pretty boring example, the idea might come in handy for >> something like a graph node, or linked list node (etc). Anyway, the >> problem I have is the way this works: >> >> case x >> when Array puts "Array" >> when Proxy puts "Proxy" >> end > > If you really have to do this kind of thing, a work-around you might try > is: > > result = case x.class.new > when Array then "Array" > when String then "String" > when Proxy then "Proxy" > end > result # => "String" > > That's kind of ugly, but then I think using case statements to > distinguish the class of an object is kind of ugly under any circumstances. It's not only ugly it probably also does not make much sense because the OP wants to test "x" and not "x.class.new". A better solution would be to use the second form of "case" to have more control over the test case when Array == x.class when String == x.class end An alternative way is to build custom testers: ARRAY = lambda {|x| Array === x.class} def ARRAY.===(o) self[o] end case x when ARRAY ... end Viewing this more abstract: maybe case isn't even the right thing to do. We would have to know more about what the OP is trying to accomplish. On an even more general level there is a certain contradiction between having something behave exactly like an Array - but also different... :-) Kind regards robert