in reply to Dynamic Package Name & Subroutine Call

A package is just a namespace identified by a string.

package Test::One; sub hello{ my $var = shift; print "Hello: $var\n"; } 1; package Test::Two; sub hello{ my $var = shift; print "Hello: $var\n"; } 1; package main; use strict; use warnings; use Data::Dumper; my @pkgs = qw( One Two ); foreach my $pkg ( @pkgs ) { "Test::$pkg"->hello(); }

This is one step toward full-fledged classes and objects, which may be a better solution in the longrun: perlobj.

If you can't plan on passing the package name as the first parameter (which is what the Class->method() notation does), then you have to construct the fully qualified sub name, which means symbolic references and some ugly syntax:

foreach my $pkg ( @pkgs ) { no strict 'refs'; &{'Test::' . $pkg . '::hello'}($pkg); }

Update: Good job on figuring out the symbolic ref syntax on your own. Looks like we both came up with the same.


Dave

Replies are listed 'Best First'.
Re^2: Dynamic Package Name & Subroutine Call
by tobyink (Canon) on Dec 15, 2012 at 07:57 UTC

    An alternative to no strict 'refs' would be:

    foreach my $pkg ( @pkgs ) { my $hello = "Test::$pkg"->can('hello'); $hello->() if $hello; }

    ... because can returns a coderef. In the case of packages that have inheritance (@ISA) this will act slightly differently to &{'Test::' . $pkg . '::hello'}().

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      can should be used for methods and only for methods, so that should be

      my $full_pkg = "Test::".$pkg; my $hello = $full_pkg->can('hello'); $full_pkg->$hello(...); # Or: $hello->($full_pkg, ...);

      which simplifies to:

      my $full_pkg = "Test::".$pkg; $full_pkg->hello(...);

      You don't even need can if the method name is variable.

      $full_pkg->$method_name(...);

        can should be used for methods and only for methods

        that boat has sailed a long time ago :)