From: Charles Oliver Nutter Date: 2007-12-27T05:49:19+09:00 Subject: Re: Some Ruby 1.9 loose ends to tie up Paul Brannan wrote: > Charlie and I were talking about this at Rubyconf. It seems silly to me > that a method called like this: > > foo { } > > can access the caller's local variables, but a method called like this: > > foo() > > cannot. It feels like taking advantage of an unintentional side-effect > of passing in a block. > > I think a lot of this sort of magic would be a lot cleaner and more > easily optimizable if foo were a macro rather than a method call. I don't know about macros, but the idea that passing a block opens up your local scope to modification by the caller seems pretty wrong to me. I agree with your side-effect comment. This feature works just because it *can* work. >> JRuby "pretends" that eval, binding, and other methods are keywords, >> since the only cases where they won't be their normal selves is if >> they're aliased (which nobody does). Other methods in the system have >> similar treatment. By assuming that "eval" always means eval, we can >> optimize specific scopes to use Java stack for local variables. > > Do you explicitly disallow aliasing these methods? Not at the moment. I've intentionally left it this way to see if it breaks for anyone. We may disable aliasing those methods for 1.1 final release. > How would you handle this: > > irb(main):001:0> o = Object.new > => # > irb(main):002:0> b = o.send(:binding) > => # > irb(main):003:0> eval("o", b) > => # > > If they eval and binding are keywords, I think this should fail. It does fail in current JRuby; o comes out "nil". But nobody does this. If it turned out to be a use case that broke some code someone was concerned about, the fix in JRuby would be to also look for "send" calls to "binding" and friends. Another option would be for JIT mode...if such calls are actually calling binding and friends, we would track that and compile them differently later. So far, neither change has been necessary. >> If eval, binding, etc, or a block are present, JRuby falls back on a >> heap-based structure. If procs could not be bindings, we could fall back >> for only specific variables, leaving the others on the stack (a >> technique that IronRuby and XRuby use, but which will break in the >> presence of proc-as-binding). > > Which variables would need to be placed on the heap in this case? Only variables that need to be accessible across call boundaries would have to be on the heap. So in this case, b could be on the stack (or in a register) while o would go on the heap. Of course I assume we're talking about real code, not IRB. In IRB, everything generally resolves to eval'ed code executing within a heap-based binding. - Charlie