20

I know it is possible to use a variable as a variable name for package variables in Perl. I would like to use the contents of a variable as a module name. For instance:

package Foo;
our @names =("blah1", "blah2");
1;

And in another file I want to be able be able to set the contents of a scalar to "foo" and then access the names array in Foo through that scalar.

my $packageName = "Foo";

Essentially I want to do something along the lines of:

@{$packageName}::names; #This obviously doesn't work.

I know I can use

my $names = eval '$'. $packageName . "::names" 

But only if Foo::names is a scalar. Is there another way to do this without the eval statement?

2
  • What do you mean by "access Foo"? Commented Apr 15, 2010 at 19:56
  • Edited the question. I want to be able to access the package variable "@names" within foo Commented Apr 15, 2010 at 19:58

2 Answers 2

19

To get at package variables in package $package, you can use symbolic references:

no strict 'refs';
my $package = 'Foo';

# grab @Foo::names
my @names = @{ $package . '::names' }

A better way, which avoids symbolic references, is to expose a method within Foo that will return the array. This works because the method invocation operator (->) can take a string as the invocant.

package Foo;

our @names = ( ... );
sub get_names { 
    return @names;
}

package main;
use strict;

my $package = 'Foo';
my @names = $package->get_names;
Sign up to request clarification or add additional context in comments.

4 Comments

I think I like the alternative method you described, long as I can define get_names in Foo's base class (we'll call it Bar to be original) that way I can just define @names in every class which inherits from Bar. I'm using Moose objects if that makes any difference.
@Paul, parens are not required on method calls if there are no arguments. Some people prefer to always include an empty () for consistency, but I generally leave them out if I can.
Gotcha. I prefer the consistency personally.
You can consistentially leave off parens, too. That's consistent. :)
5

Strict checking is preventing you from using a variable (or literal string) as part of a name, but this can be disabled locally:

my @values;
{
    no strict 'refs';
    @values = @{"Mypackage"}::var;
}

4 Comments

Essentially what I'm doing is globbing a directory for *.pm and then for each file I find I require $filename. Once those modules are loaded I then need to access the @names variable defined inside each package. I don't know the package's name until runtime, all I have is a variable which will contain the name of the package.
I'm not have a problem loading packages from a variable name - I've got that part down. Its accessing the variables within those packages. This answer would have definitely save me a lot of googling an hour ago though :)
@mjn: oops sorry, I'm editing my answer now to make the real issue more prominent :)
When I try this solution on Perl v5.30.1, I get an error: “Bareword found where operator expected at test15.pl line 4, near "}::var" (Missing operator before ::var?) syntax error at test15.pl line 4, near "}::var"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.