masak (>>), coke (>): > > <masak> nom: my $c; my $name; BEGIN { $c = { say "OH HAI $name" } }; > > $name = "masak"; $c() > > <p6eval> nom ea25f3: OUTPUT«Use of uninitialized value in string > > contextOH HAI » > > <masak> I'd expect the above to say "OH HAI masak". > > <masak> are my expectations too high? :) > > <jnthn> masak: Seems reasonableish... :) > > * masak submits rakudobug > > I would expect $name to be undefined at BEGIN time, which would make > this behavior correct. > > Can you explain your POV here?
Yes. $name is indeed undefined (or Any) at BEGIN time, but we're not calling it at BEGIN time. The order of things is this: 1. Parse declarations of $c and $name. These are in scope for the rest of the program, and there's only one runtime environment with these variables in it -- the mainline one. 2. Parse BEGIN block. Since it's a BEGIN block, the assignment to $c happens immediately, at compile time. 3. Parse the rest of the program. Parsing completes. 4. Switch from compile time to runtime. 5. Make the assignment to $name. 6. Make the invocation $c(). 7. Now inside the Block assigned to $c. In order to print the string, look up $name, which (there being only one, the one in the mainline code) should now have the assigned value "masak". Print it. Something goes wrong in step 7, since the value looked up for $name comes up as Any, not "masak". The thing that goes wrong is that the compile-time value for $name is found, not the run-time value. The real cause/problem actually happens in step 2, when the block assigned to $c gets incarnated (=given a runtime representation with a runtime environment and its lexical bindings). It should get incarnated to eventually make the lookup finding "masak" in $name. Whereas it currently behaves, even when called from runtime, like it's still BEGIN time and $name is still unassigned. Or maybe the error is in fact at step 4, because at step 2 when can't do much better than we already do, since we're not at runtime yet, and there's no runtime environment with a runtime $name to incarnate into yet. So maybe at step 4 we need to "upgrade" the Block to have a runtime environment. Or maybe it's unrealistic/slow/impossible to thus upgrade all Blocks during the transition from compile time to runtime, and the best we can do is simply to upgrade them ALAP, when called, at step 6. I don't know enough about the internals to know which one is the best solution. Hope that helps.