From: Austin Ziegler Date: 2005-10-20T05:57:54+09:00 Subject: Re: Anonymous methods, blocks etc. (Cont. 'default block params') On 10/19/05, Trans wrote: > Austin Ziegler wrote: >> I'm not wanting to extrapolate. Consider me the conservative here, >> Trans. Convince me that this is really useful and important. > It's all relative Austin. How *really useful and important* is > anything? 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. 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. > Most things can be done in some other way. But this much is certain, > there are things you CAN'T do b/c of this -- or at least not wihtout > jumping through some magical hoops like defining a method grabing the > UnboundMethod, converting to_proc and undefining the method (which I > have done). 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. > 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. >>>> This isn't a closure problem. This is a constant lookup problem, and >>>> Matz has said that this should be fixed moving forward. >>> It has to do with closures in that the reference to constants is >>> relative to the given closure. So the current behavior is correct. A >>> non-closure block will allow the needed alternate behavior. >> Not by my understanding. Constant lookup is handled separately from >> closure rules, which mostly deals with local variables. That is to >> say that: >> >> class X; end >> Y = Class.new(X) do >> X = Class.new do >> end >> end >> >> is and should be different than: >> >> class X; end >> >> x = X >> p x # X >> >> Y = Class.new(X) do >> x = Class.new do >> end >> const_set("X", x) >> end >> >> p x # Y::X >> >> Closure rules don't ahve anything to do with constant lookup, at >> least at this point. > ^^^^^^^^^^^^^ > > 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. -austin -- Austin Ziegler * halostatue@gmail.com * Alternate: austin@halostatue.ca