6

Why isn't the value of a variable with := binding exported?

$ cat myModule.pm6 
our $a is export = 42;
our $b is export := $a;

$ cat program.p6 
use myModule;
say $a;
say $b;

$ perl6 program.p6 
42
(Any)   # Why?
Eugene Barsky
  • 5,780
  • 3
  • 17
  • 40

1 Answers1

8

An our-scoped variable is really just a lexical variable (like my) that - instead of having a Scalar freshly created per scope - is initialized by being bound to a symbol of that name in the Stash of the current package. So effectively, this:

our $foo;

Is doing this:

my $foo := $?PACKAGE.WHO<$foo>;

And so:

our $foo = 42;

Is doing this:

(my $foo := $?PACKAGE.WHO<$foo>) = 42;

Rebinding the symbol thus means it's no longer associated with the Scalar container stored in the Stash.

Exporting an our-scoped variable exports the Scalar container from the stash that the variable is bound to at scope entry time. Thus the assignment assigns into that exported Scalar container. By contrast, binding replaces the lexical with something entirely different and unrelated to what was exported.

This is why you aren't allowed to export a my-scoped variable: a fresh Scalar is bound every scope entry, but exportation is a compile-time thing, so there would be no way to ever modify the thing that was exported.

Jonathan Worthington
  • 29,104
  • 2
  • 97
  • 136
  • 1
    It would be possible to read jnthn's answer and think he's saying there's no bug. I don't think he means to convey that. See his comments in the bug report [Binding a variable at BEGIN time doesn't stick aruond for runtime](https://rt.perl.org/Public/Bug/Display.html?id=123776). – raiph Oct 18 '18 at 13:05
  • 1
    @raiph There is no bug in this case (which is not identical to the one you linked). – Jonathan Worthington Oct 18 '18 at 14:16
  • 1
    I get that the bug I linked is a different scenario but saying this isn't a bug is a bit shocking. Are you saying that your comment in the bug I linked that "We should perhaps detect it at compile time and say it can't work." still applies to the existing bug but not the scenario covered in this SO? And is there no chance at all of "we could try ... to somehow propagate bindings" (even if it's even less appealing to think about actually doing such a thing for the scenario in this SO)? – raiph Oct 18 '18 at 16:18
  • 2
    @raiph We certainly could warn that binding to an `our` variable is pointless use of `our`. As explained, the issue here is not specific to `export`. – Jonathan Worthington Oct 18 '18 at 16:35