On Wed, 26 May 2004, Robert Klemme wrote:

[cut]
> 
> The only problem I can see at the moment is with classes that are not in the
> global scope:
> 
> >> module Foo; class Bar; end; end
> => nil
> >> Foo::Bar
> => Foo::Bar
> >> Foo::Bar.to_s
> => "Foo::Bar"
> 
> This string is likely to make problems in a method name:
> 
> >> class X
> >> def visit_Foo::Bar
> >> end
> >> end
> NameError: undefined local variable or method `visit_Foo' for X:Class
>         from (irb):5
> 
> 
> Maybe you just map "::" to "_" or something similar.
> 

Shoot I completely forgot about that problem.  Hmm that causes all
sorts of problems.  I can't simply do a gsub(/::/,'_') because then
what would happen if you wrote:

class A::B
end

and

class A_B
end

They would be indistinguishable.  I suppose you could just take that
into account and do something like split(/::/)[-1] and just assume you
don't have a naming collision.  I would think that generally you would
be only interested in the class of the most immediate scope, but it
certainly allows for some ambiguity.  

Speaking of which what is up with this:
irb(main):115:0> "a::b::c".intern
=> :"a::b::c"

Is that syntax documented?


> An alternative approach could be to use the visitor to get a proc for the
> current instance, like in
> 
> class Visitor
>   def visit(obj)
>     bl = nil
> 
>     obj.class.ancestors.each do |cl|
>       bl ||= visitors[cl]  # hash lookup
>     end
> 
>     bl.call( obj ) if bl
>   end
> end
> 

Something like that would certainly work it just doesn't seem as nice a way to
define each visitor.  Hmm I shall have to think on this.  

Charlie