Austin Ziegler wrote:
>
> Don't try that game with me, Trans. You can't play it that well. You're
> wanting a new feature that I don't think makes any sense at all. Matz,
> so far, has said things publicly that seem to indicate that he's
> unconvinced of the need for this as well (or at least doesn't plan on
> making it happen). What I'm really trying to get you to do is to write
> an RCR stronger than that which you wrote for AOP for this. If you
> convince Matz that we need this, then more power to you.

*Convince* Matz? Hah! Haven't you noticed he's a like rock? But thank
goodness, right? Maybe I can nudge him a bit...maybe an RCR in due
time, after I finish some other stuff.

> You don't have to convince me first, either. But so far, all I've heard
> are what amount to "I don't get constant scoping" (and Matz has said
> this is going to be fixed) and "cut and paste dumb programmer" issues.
> If that's the best you can offer, I doubt you'll be able to convince
> Matz of the need for it, either. We're getting a little more to the
> heart of the possibilities now, I think.

Sure. Usecases don't grow on trees. We're both working on assumptions
here: you that there are no worthy uses, me that there are. I've come
across a few spots where they could be useful (and I still think
constants aren't exactly foreign to the issue) but it's not like I've
been collecting them for this very day.

Nonetheless, I just happend upon one. Took me by surprise too, cause I
wasn't even thinking about it and couldn't understand the bug at
first... until I realized...

Simplifed for easy illistration:

  module Kernel
    def do_this_on( klass, &blk )
      o = klass.new( self )
      o.instance_eval( &blk )
    end
  end

  x = "Hop"

  class Pop
    def initialize( o )
      @o = o
    end
    def x ; "#{@o} on Pop" ; end
  end

  x.do_this_on Pop do
    p x
  end

Stupid example? Think about #with_namespace that everyone's chatting
about these days rather than #do_this_on and its not so stupid anymore.

> Why? What *need* do you have to grab an UnboundMethod, convert it to a
> proc, and then undefine the method? In the three and a half years that
> I've been working with Ruby, I haven't needed a UnboundMethod once, much
> less needing to do what you've described here. And, I'd argue, if what
> you're doing is bizarre/dangerous enough, then maybe you *need* to be
> going through those hoops in order to make it so that such functionality
> is unlikely to be abused.

I do a lot of language abstraction stuff --meta programming. The
particular case was to create Module::class_inherit, an improvement
over using ClassMethods.

Speaking of the "game" you just lost a point for never using
UnboundMethod ;)

Just kidding. I am suprised you've never used it though.

> > But as to the example I was trying to show here... here's something a
> > little bit more real-to-life, though still off the top of my head.
> >
> >   dir = File.dirname(__FILE__)
> >
> >   m = Module.new do
> >     make_dir_method = lambda { |which, path|
> >       class_eval {
> >         define_method( "#{which}dir" ) { |name|
> >           dir = File.dirname(path)
> >           name = File.basename(path)
> >           File.join(dir,which,name)
> >         }
> >       }
> >     }
> >
> >     make_dir_method.call('lib',dir)
> >     make_dir_method.call('var',dir)
> >     make_dir_method.call('bin',dir)
> >   end
>
> So ... you're trying to essentially do:
>
>   m = Module.new
>   class << m
>     def libdir(name)
>       dir  = File.dirname(File.dirname(__FILE__))
>       name = File.basename(name)
>       File.join(dir, 'lib', name)
>     end
>   end
>
> Yes, I know I did manually what you're trying to do automatically, but
> I'm trying to understand here. I'm sure with a bit more thought, I could
> come up with something cleaner to do this -- although I'm not really
> understanding *why* you want to do this, in any case. FWIW, in 1.8.2 I
> didn't get a compile error except from the fact that your code used the
> 1.9 deprecated () on lambdas.

The why of it is to ease the creation of some dynamic methods. It's not
a particular example, mind you, it's still just something I made up at
the spur of the moment to point out that under certain situations one
might get a "gotchya" because the lambda isn't isolated. Sure you could
get around this and make an actual def, but sometimes you don't really
need the procedure to hang around wasting memory, it's just a temp
thing, like a local var.

> >
> > Doesn't it seem just a little odd that this causes an error?
> >
> >   class X
> >     Y = 1
> >   end
> >
> >   X.class_eval { Y }
>
> No. Because constants are defined separately from closures.
>
> > I know, I know. It makes total sense with how Ruby works. Not so sure
> > how Ruby works makes total sense. Honestly, how can closure NOT be of
> > significant to constant lookup?
>
> Because, to be honest, I don't see any reason that they *should* be
> significant to constant lookup. To me, there's other places where
> constant lookup should be fixed -- but closures ain't one of them.
>
> I've got a much bigger problem with:
>
>   class X
>     Y = 1
>   end
>
>   class X::Z
>     Y
>   end
>
> vs.
>
>   class A
>     B = 1
>     class C
>       B
>     end
>   end
>
> ..than I'll ever have with lambdas and blocks using the constants from
> their current context.

Hey man, I'm with ya. I just think closure can't be exceptional to
this. Shouldn't constant lookup be relative to the closure? In fact, if
it were it might solve your bigger problem too.

T.