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

For example:
use 5.012; use warnings; package Zelda; our $type = "prince"; package Mario; our $type = "hero"; package Kupa; our $type = "villan"; package main; foreach my $pkg (qw/Zelda Mario Kupa/) { print "$_ is a " . $$pkg::type . "\n"; #ERROR! print "$_ is a " . ${$pkg}::type . "\n"; #ERROR! print "$_ is a " . ${$pkg::type} . "\n"; #ERROR! }
What to do :( ???

Replies are listed 'Best First'.
Re: How do I interpolate package name in a fully qualified name?
by Anonymous Monk on Apr 21, 2011 at 02:33 UTC
    package Zelda; our $type = "prince"; package Mario; our $type = "hero"; package Kupa; our $type = "villan"; package main; foreach my $pkg (qw/Zelda Mario Kupa/) { print ${$pkg.'::type'}, "\n"; } __END__
    But seriously, isn't this what objects are for ?:)
      ... isn't this what objects are for?

      Second that. (And strictures don't have to be turned off.)

      >perl -wMstrict -le "{ package Zelda; sub type { shift; return 'prince'; } } ;; { package Mario; sub type { shift; return 'hero'; } } ;; { package Kupa; sub type { shift; return 'villan'; } } ;; foreach my $pkg (qw/Zelda Mario Kupa/) { printf qq{$pkg is a %s \n}, $pkg->type; } " Zelda is a prince Mario is a hero Kupa is a villan

      Update: Note: The  shift; in each of the
          sub type { shift;  return 'whatever'; }
      subroutine definitions was intended only to point up the fact that a string representing the package (or class) name is implicitly passed as the first argument to any class method (which this subroutine is). Because the method does not interact with the argument list in any way, it is not needed.

        OK, Both of them are working. Thank you.
Re: How do I interpolate package name in a fully qualified name?
by wind (Priest) on Apr 21, 2011 at 02:36 UTC

    eval works:

    print "$pkg is a " . eval("\$${pkg}::type") . "\n";

    Yeah, as Anon monk posted, you can do the following, but you'll have to turn off strict refs. Still can't think of a way to avoid having to play with strict.

    no strict 'refs'; print "$pkg is a " . ${$pkg.'::type'} . "\n";
      I ain't scared of "no strict refs" :) On the other hand, I am very scared of eval stuff :( I guess I will use the second one of your examples. Thank you.
Re: How do I interpolate package name in a fully qualified name?
by Mr. Muskrat (Canon) on Apr 21, 2011 at 18:52 UTC

    There are plenty of good answers here so I won't bother trying to give yet another.

    I will, however, point out that you are confused. Zelda is a princess and not a prince. She is from a different game franchise than Mario and Koopa (which is not spelled 'Kupa' and they are really henchmen and not villains). :D

      Ok, you are right:);
      But, actually I was got confused between prince and princess, not Zelda being she, hehe...
        plus, mistaken Peach for Zelda. OOPS
Re: How do I interpolate package name in a fully qualified name?
by Khen1950fx (Canon) on Apr 21, 2011 at 08:35 UTC
    Using fields, I tried it without a foreach:
    #!/usr/bin/perl use 5.012; use warnings; { package Example; use fields qw(Zelda Mario Kupa _Example_private); sub new { my Example $self = shift; unless (ref $self) { $self = fields::new($self); $self->{_Example_private} = "Inspection of Ex +ample"; } $self->{Zelda} = 'prince'; $self->{Mario} = 'hero'; $self->{Kupa} = 'villan'; return $self; } } package main; my $type = Example->new; print "Zelda is a ", $type->{Zelda}, "\n", "Mario is a ", $type->{Mario}, "\n", "Kupa is a ", $type->{Kupa}, "\n";
      I'll try this when I need to ofuscate my code. :)
      Thank you for the answer.