Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are our variables dynamic?

Tags:

scope

raku

This code will print out 'Duo' even though $var is not a dynamic variable with a * twigil:

our $var="Duo";
sub sub1() {
    say $*var;
}

sub1();
#output is 'Duo'

Adding a unit package ABC; at the start gives a compile time error "Dynamic variable $*var not found":

unit package ABC;

our $var="Duo";
sub sub1() {
    say $*var;
}

sub1();
# compile time error

Adding a * twigil in this case makes the variable accessible.

Why the difference?

Edit 1:

Using my instead of our is a compile time error with or without a package, even though this would mean the same lexical scope in my understanding.

Are variables which are intended to be used dynamically, to be declared explicitly as such (like all the examples I can find). If so how does our allow the above to work? I'm confused.

Edit 2:

I think the following demonstrates why I'm confused:

our $var="non dynamic";   #1
{say $*var;}

our $*var="dynamic";      #2
{say $*var;}


#With #2 commented output is
#non dynamic
#non dynamic
#
#With #2 in place output becomes
#(Any)
#dynamic

In the first case (#2 commented) I'm accessing a non dynamic variable dynamically (twice).

In the second case the our $var variable is getting clobbered when the our $*var is declared and accessing same dynamic variable is resolving to two seperate variables.

like image 364
drclaw Avatar asked Apr 03 '19 11:04

drclaw


People also ask

Are variables static or dynamic?

Static variables (should) remain the same e.g. temperature of a water bath, k constant of a particular spring. Dynamic variables change as the experiment progresses e.g. air temperature and pressure, amount of natural light.

Are variables in C static or dynamic?

In C, variables are always statically (or lexically) scoped i.e., binding of a variable can be determined by program text and is independent of the run-time function call stack.

Is time a dynamic variable?

Physical observable intrinsic to a system (so time is not a dynamical variable).


2 Answers

Seems like dynamic variables are looked up in the GLOBAL name space. Thus the following works:

unit package ABC;

$GLOBAL::var="Duo";
sub sub1() {
    say $*var;
}
sub1();
#output is 'Duo'

The reason your first example works is that (according to the documentation):

The user's program starts in the GLOBAL package, so "our" declarations in the mainline code go into that package by default.

like image 121
Håkon Hægland Avatar answered Sep 28 '22 12:09

Håkon Hægland


Dynamic variable lookup conceptually happens in all dynamic scopes. Dynamic scopes are first PROCESS::, then GLOBAL:: and then whatever dynamic scopes that the program has.

So when you look up a dynamic variable, it will first look in all dynamic scopes from the current down. When it doesn't find it there, it will then look in GLOBAL::, and if not found, in PROCESS::.

For example, if you want to print something on STDOUT, it will look up the $*OUT dynamic variable. If you did not define one somewhere in your dynamic scopes, it will use the one from PROCESS:::

dd PROCESS::<$OUT>;
# IO::Handle element = IO::Handle.new(path => IO::Special.new("<STDOUT>")...)
like image 36
Elizabeth Mattijsen Avatar answered Sep 28 '22 13:09

Elizabeth Mattijsen