From: "T. Onoma" Date: 2003-11-28T11:28:28+09:00 Subject: Re: Controlled block variables On Friday 28 November 2003 02:31 am, Gavin Sinclair wrote: > Actually, this is the problem: > NoMethodError: undefined method `class_eval' for main:Object > > Or did you mean the above code to exist within a class? If so, I have: > > class X > a = [1,2,3] > class_eval { > def ameth > p a > end > } > end > > X.new.ameth > # NameError: undefined local variable or method `a' for # > # from (irb):13:in `ameth' > So 'a' is not evaluated as nil, it cannot be evaluated. Ooops. You're right, not nil, rather unknown. I was thinking @a, which would be nil b/c it gets substantiated upon use. > I hate to ask at this late stage, but what's the problem? If you want to > make the value 'a' available to the dynamically created method 'ameth', > maybe you could try this > > class Z > @@a = [1,2,3] > class_eval { > def ameth > @@a.length > end > } > end > > Z.new.ameth # => 3 > > If you don't know in advance what your variable names are going to be, use > a hash. You don't have to resort to global variables; class variables are > there to help. And so am I :) That was basically Ryan's soluiton. (on ruby-core) But again it's really just a work around. The "problem", if we disect it to its roots, is two-fold. The first is a discrepency in eval's scope ability when a string it used versus a block: eval "#{a}" eval {a} Mind you, I do understand what's going on that makes this happen. That's not the problem. Rather, from the point of view of a user, or POLS, if you will, that the scope changes, is discongruous. And is not even apparent from this example b/c it isn't an issue here. It is only when you do something like eval "def ameth; #{a}; end" eval {def ameth; a; end} that the change becomes evident. The second problem then derives from the first, b/c now, in order to get the greater scope that the string "version" of eval offers, one has to convert the objects into literals. Which is a pain and also is inefficient, considering that the object's already "right there!". I think for a Ruby expert this may be hard to comprehend becasue you understand what Ruby is doing so well, it is almost second nature. But take a step back and really look at this from a nuby's point of view (the spirit of POLS in my opinion). Then consider: "With a string I can get to a but I have to make it a literal." "With a block I don't need the literal, but I can't get to a." -t0