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.