2

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?

Elizabeth Mattijsen
  • 25,654
  • 3
  • 75
  • 105
danielschemmel
  • 10,885
  • 1
  • 36
  • 58

1 Answers1

5

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.

Christoph
  • 164,997
  • 36
  • 182
  • 240
  • While simply using `$*param` kills the program, all your other solutions work perfectly fine :) (`try $*param` gives `(Any)` on my system though) – danielschemmel Oct 29 '15 at 20:39
  • 1
    @gha.st: works on my Rakudo build (2015.09-400-g68563f4); note that the use of `//` (or `$*param.defined` for that matter) is required - it will prevent the failure from getting thrown, cf `perl6 -e 'say $*foo.WHAT'` and `perl6 -e 'say $*foo // 42'` vs `perl6 -e 'say $*foo'` – Christoph Oct 29 '15 at 20:44
  • Aaand, now I feel truly stupid - I actually managed to add a typo and use only a single `/`.... – danielschemmel Oct 29 '15 at 20:47