4

I have a name which I'd like to give to a variable, in another string variable: my $name = '$a'; or simply my $name = 'a'; How to make the variable and to use it? I mean something like this (but it doesn't work):

my $name = '$a';
my {$name} = 1; # Doesn't work
say $a; # should be 1

A more general case. I have a list of variable names, say my @names = '$aa' ... '$cc'; How to declare and use the variable, whose name will be e.g. @names[2]?

Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
Eugene Barsky
  • 5,780
  • 3
  • 17
  • 40
  • If you want this, you're thinking wrongly about the problem. This is about Perl5, but nevertheless valid here: http://perl.plover.com/varvarname.html – Holli Nov 16 '17 at 15:15
  • @Holli I wasn't thinking about using it with some hash-like data, I was just wondering how to do it. :) Thanks for the link! – Eugene Barsky Nov 16 '17 at 15:21
  • 1
    This might interest you: https://docs.perl6.org/language/packages#Looking_up_names . But that's for name lookup, not declaration. I think lexical name declaration must be explicit so the compiler can check that variables exist. But when a package is imported, it can export dynamically named variables and functions. If you want to do this with a module, a recent question perl6 question by Holli has two answers that describe it. – piojo Nov 16 '17 at 15:43

2 Answers2

3

According to documentation the lexical pad (symbol table) is immutable after compile time. Also (according to the same docs) it means EVAL cannot be used to introduce lexical symbols into the surrounding scope.

I suggest you use package variables, instead of lexical variable as suggested in the comments.

However, a workaround is possible: You can create your own lexical pad at run time (for the module requiring) using for example require MODULE:

my $name = '$a';
spurt 'MySymbols.pm6', "unit module MySymbols; use v6; my $name = 1; say \"\\$name = $name\"";
use lib '.';
require MySymbols;

Output:

$a = 1
Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
3

Lexical scopes are immutable, but the way you would do it is ::($name) or MY::($name).

my $a; # required or it will generate an error

my $name = '$a';

::($name) = 1;
say $a;          # 1

MY::($name) = 2;
say $a;          # 2

sub foo ($name,$value) { CALLER::MY::($name) = $value }
foo($name,3);
say $a;          # 3
Brad Gilbert
  • 33,846
  • 11
  • 78
  • 129
  • 1
    Good idea, but the top `my $a` could be a problem? As I understood the question, the variable name `$a` should be inside another variable (meaning here: a string created on the fly), so I did not think an explicit `my $a` would be an option. – Håkon Hægland Nov 17 '17 at 05:12
  • @HåkonHægland He was really asking two questions at once. The answer to if it is possible to dynamically create new variables is *no*, but the answer to how to dynamically access them is what I wrote. – Brad Gilbert Nov 17 '17 at 20:15