In Perl, is there any difference between direct glob aliasing and aliasing via the stash?

Maybe not the kind of difference you were looking for, but there are two big differences between *main::foo and $main::{foo}; the former looks up the glob in the stash at compile time, creating it if necessary, while the latter looks for the glob in the stash at run time, and won't create it.

This may make a difference to anything else poking about in the stash, and it certainly can affect whether you get a used only once warning.


The following script:

#!/usr/bin/env perl

#mytest.pl

no warnings;


$bar = "this";
@bar = qw/ 1 2 3 4 5 /;
%bar = qw/ key value /;

open bar, '<', 'mytest.pl' or die $!;

sub bar {
    return "Sub defined as 'bar()'";
}
$main::{foo} = $main::{bar};

print "The scalar \$foo holds $foo\n";
print "The array \@foo holds @foo\n";
print "The hash \%foo holds ", %foo, "\n";
my $line = <foo>;
print "The filehandle 'foo' is reads ", $line;
print 'The function foo() replies "', foo(), "\"\n";

Outputs:

The scalar $foo holds this
The array @foo holds 1 2 3 4 5
The hash %foo holds keyvalue
The filehandle 'foo' is reads #!/usr/bin/env perl
The function foo() replies "Sub defined as 'bar()'"

So if *main::foo = *main::bar; doesn't do the same thing as $main::{foo} = $main::{bar};, I'm at a loss as to how to detect a practical difference. ;) However, from a syntax perspective, there may be situations where it's easier to use one method versus another. ...the usual warnings about mucking around in the symbol table always apply.


Accessing the stash as $A::{foo} = $obj allows you to place anything on the symbol table while *A::foo = $obj places $obj on the expected slot of the typeglob according to $obj type.

For example:

  DB<1> $ST::{foo} = [1,2,3]

  DB<2> *ST::bar = [1,2,3]

  DB<3> x @ST::foo
Cannot convert a reference to ARRAY to typeglob at (eval 7)[/usr/local/perl/blead-debug/lib/5.15.0/perl5db.pl:646] line 2.
 at (eval 7)[/usr/local/perl/blead-debug/lib/5.15.0/perl5db.pl:646] line 2
    eval '($@, $!, $^E, $,, $/, $\\, $^W) = @saved;package main; $^D = $^D | $DB::db_stop;
  @ST::foo;

;' called at /usr/local/perl/blead-debug/lib/5.15.0/perl5db.pl line 646
    DB::eval called at /usr/local/perl/blead-debug/lib/5.15.0/perl5db.pl line 3442
    DB::DB called at -e line 1
  DB<4> x @ST::bar
0  1
1  2
2  3
  DB<5> x \%ST::
0  HASH(0x1d55810)
   'bar' => *ST::bar
   'foo' => ARRAY(0x1923e30)
      0  1
      1  2
      2  3