As I understand, Dynamic Variables are looked up at runtime. I want to use them to enable parametrization similar to racket parameters.
To do so, I have to set a default that should be overridable, but not necessarily changable. My current approach is fairly simplistic:
my $*param ::= 42;
sub parameterized-function { say $*param };
parameterized-function();
do {
my $*param ::= 15;
parameterized-function();
}
Which works just fine - except that it introduces the name of the parameter on the outer scope. Beyond just feeling untidy, this has the side-effect that my $*param = 15;
causes mayhem if used on the file level.
What I would like to do instead is check if the parameter has been defined on the call stack, along the lines of:
sub parameterized-function { if defined($*param) { say 42 } else { say $*param } };
So, is it possible to perform such a check, if so how is it done?
Quoting S02:
User-defined dynamic variables should generally be initialized with
::=
unless it is necessary for [the] variable to be modified. (Marking dynamic variables as readonly is very helpful in terms of sharing the same value among competing threads, since a readonly variable need not be locked.)
If you want to access a dynamic variable that has not been defined in the current (dynamic) scope, either of the following should work:
$*param // 'default value'
# Any if not found
DYNAMIC::<$*param>
# Nil if not found
try $*param
# Mu if not found
use nqp;
nqp::getlexdyn('$*param')
As I have not looked into what you're trying to accomplish, there might be more appropriate solutions.