В Perl, есть ли разница между прямым псевдонимом и псевдонимом глобуса через тайник? - PullRequest
8 голосов
/ 07 июля 2011

В Perl, есть ли разница между следующими двумя конструкциями:

*main::foo = *main::bar

и

$main::{foo} = $main::{bar}

Похоже, они выполняют одну и ту же функцию (совмещая все слоты в *main::foo с определенными в *main::bar), но мне просто интересно, всегда ли выполняется эта эквивалентность.

Ответы [ 3 ]

9 голосов
/ 07 июля 2011

Возможно, не та разница, которую вы искали, но есть две большие разницы между *main::foo и $main::{foo}; первый ищет глобус в тайнике во время компиляции, создавая его при необходимости, в то время как последний ищет глобус в тайнике во время выполнения и не создает его.

Это может иметь значение для всего остального в тайнике, и это, безусловно, может повлиять на то, получите ли вы used only once предупреждение.

3 голосов
/ 07 июля 2011

Доступ к хранилищу с помощью $A::{foo} = $obj позволяет вам поместить что-либо в таблицу символов, в то время как *A::foo = $obj помещает $obj в ожидаемую ячейку typeglob согласно типу $obj.

Например:

  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
3 голосов
/ 07 июля 2011

Следующий скрипт:

#!/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";

Выходы:

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()'"

Так что, если *main::foo = *main::bar; не делает то же самое, что $main::{foo} = $main::{bar};, я в растерянностиотносительно того, как обнаружить практическую разницу.;) Однако, с точки зрения синтаксиса, могут быть ситуации, когда проще использовать один метод по сравнению с другим.... всегда применяются обычные предупреждения о том, что они могут заглядывать в таблицу символов.

...