GG1985 has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

Can someone explain why using the symbolic reference instead of type glob in the package import method for exporting symbols raises errors?

Examples below.
Example 1: ========================= Sample.pl: ---------- #!/usr/bin/perl -w use strict; use Zoo; print $pet, "\n"; Zoo.pm: ------- package Zoo; our $pet = "Cat"; sub import { my $package = shift; my ($callerpkg, $file, $lineno) = caller; ################# # Type-glob below ################# *{"${callerpkg}::pet"} = \${"${package}::pet"}; } 1; Output: ------- >./sample.pl Cat ========================= Example 2: ========================= Sample.pl: ---------- #!/usr/bin/perl -w use strict; use Zoo; print $pet, "\n"; Zoo.pm: ------- package Zoo; our $pet = "Cat"; sub import { my $package = shift; my ($callerpkg, $file, $lineno) = caller; #################### # Symbolic reference below #################### ${"${callerpkg}::pet"} = ${"${package}::pet"}; } 1; Output: ------- >./sample.pl Variable "$pet" is not imported at ./sample.pl line 6. Global symbol "$pet" requires explicit package name at ./sample.pl lin +e 6. Execution of ./sample.pl aborted due to compilation errors. =========================
Thanks in advance,
GG1985

Replies are listed 'Best First'.
Re: Use of typeglob in package import subroutine
by choroba (Cardinal) on Apr 29, 2014 at 15:03 UTC
    That's how use strict 'vars' works.
    [...] generates a compile-time error if you access a variable that was neither explicitly declared (using any of my, our, state, or use vars) nor fully qualified.

    Note that you can use

    print $main::pet;

    without any error, as it is fully qualified.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Use of typeglob in package import subroutine
by tobyink (Canon) on Apr 29, 2014 at 15:45 UTC

    That's just the way it works. Yeah, I know, it's weird.

    The typeglob assignment is usually what you want in exporters anyway, as it creates an alias between the two variables, rather than just copying data from one to the other.

    Also, \${"${package}::pet"} is probably better written as \$pet.

    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
      Taking the points from both replies, I summarize the following given below.

      In the example 1,

      The variable $main::pet is never declared. But, the typeglob assignment made it as an alias for $Zoo:pet which has indeed been declared with our. So 'use strict' didn't throw error since somehow $main::pet got indirectly declared.


      In the example 2,

      Here too, the variable $main::pet is never declared. The symbolic assignment just created $main::pet. So 'use strict' threw error since it could not find any declaration for $main::pet either direct or indirect.


      Any other explanation that better explain the behavior?

      - GG1985
        > $main::pet got indirectly declared.

        you can't "declare" fully qualified pkg vars, the declaration of our and my just "links" _unqualified_ vars to a slot (be in a stash or a pad) for the compiler.

        I.e. there is no need for an "implicit" declaration. It's just the same initialization like for hash-entries.

        Cheers Rolf

        ( addicted to the Perl Programming Language)