1

I have two Perl packages: pack_hash and pack_run

package pack_hash;

$VERSION    = '1.00';
@ISA        = qw( Exporter );
@EXPORT_OK  = qw( %hashInfo );

$hashInfo{abc} = ['a', 'b', 'c'];

1;

package pack_run;

use stricts;
use warnings;
use Data::Dumper;
use  pack_hash qw( %hashInfo );

somethingDoing();

sub somethingDoing {
    my $var1 = \%pack_hash::hashInfo;   # getting the hash reference
    print Dumper($var1);
    ...
    ...
}

1;

Can anyone please let me know, whether it is possible to replace the name of the hash-package (pack_hash), by using any variable, like:

my $pakVar = "pack_hash";
my $var1 = \%$pakVar::hashInfo; 

I, know it is WRONG/NOT_CORRECT, but I want this kind of symbolic ref transformation, when I'm using strictures. I also wanted to know, whether it is possible to do the thing with eval. But I want a final variable, here $var1, which will refer the particular hash (hashInfo);

  • It is not “wrong” to want this. However, I would like to know what you want to use it for. Could you please explain? – tchrist Sep 02 '11 at 17:48

2 Answers2

3

No, that is not possible. But this is:

use strict;
use warnings;
use Symbol qw<qualify_to_ref>;

my $pakVar = 'pack_hash';
my $var1   = *{ qualify_to_ref( 'hashInfo', $pakVar ) }{HASH};

qualify_to_ref takes the name of a package variable and the package name and returns a GLOB reference pointer, then you just access the HASH slot of the GLOB. You can also do it this way:

my $var1 = \%{ qualify_to_ref( 'hashInfo', $pakVar ) };

But it is just as easy to turn off strict in a very tight do as well;

my $var1
    = do {
        no strict;
        \%{ $pakVar . '::hashInfo' };
   };

I understand that some coding cultures consider turning off strict or warnings as "cheating". I know that I've had code review questions about turning off one class of warning in a small block like this. I knew which warnings I was going to get, so I didn't need it. The reviewer didn't see it this way.

For this reason some veteran Perl-ers think nothing about turning off strict. But if you can't because it makes the natives restless--you can use Symbol. However, some shops have rules against package variables, so it never becomes an issue.

Axeman
  • 29,660
  • 2
  • 47
  • 102
  • @Gaurab Banerjee, No it's not. It's *core*. http://perldoc.perl.org/index-modules-S.html and it's *beeen* core as as long as I can remember. If you have a perl installation without `Symbol`, then you really don't have Perl. – Axeman Sep 02 '11 at 14:12
  • @Gaurab: Help with what? You haven’t explained what you are trying to do. There is **nothing wrong** with turning of strict when you want to access the package symbol table; it's a lot more sensible than manipulating the stashes directly. And there is nothing wrong with using the **standard since Perl 5.000** module `Symbol`. – tchrist Sep 02 '11 at 18:08
  • qualify_to_ref was added in 5.004, so it has only been around for 14 years – ysth Sep 02 '11 at 18:51
2

If you have a class method that returns a reference to the hash:

package pack_hash;
use strict;
use warnings;
our %hashInfo;
$hashInfo{abc} = ['a', 'b', 'c'];
sub hashInfo { \%hashInfo }

then you can easily get the reference:

use strict;
use warnings;
my $pakVar = 'pack_hash';
my $hashInfo = $pakVar->hashInfo();
print @{ $hashInfo->{'abc'} };
ysth
  • 96,171
  • 6
  • 121
  • 214