Lots of good answers so far about using arrays, hashes etc, so 
won't bother going there... look below to see an OOP that works
efficiently, using NAMEs rather than refs.

> -----Original Message-----
> From: Zielfelder, Robert 
> [mailto:[EMAIL PROTECTED]] 
> Sent: 24 September 2002 18:44
> To: '[EMAIL PROTECTED]'
> Subject: Using a variable name to invoke a subroutine
> 
> foreach $sub (@list_of_subs) {
>       &{$sub};  ##-- this is the part I am stuck on.  This 
> doesn't work
> }

&{$sub}; This works if $sub contains a REFERENCE to a sub, rather 
than the NAME of a sub - you probably already figured that out.


> be invoked unless the "@list_of_subs" contains the name of 
> the sub.

So it looks like you like working with names

> that I could stick a bunch of if statements in there and make 
> this work, but
> I am trying to be a little more efficient if I can.  Any 
> insight would be

as others have said, using a hash keyed by sub name containing the 
sub references is efficient.

An alternative is to use the OOP approach - below is an example.

Note that the methods are called by NAME and not by ref. OOP is
_almost_ as efficient as your own hash. It basically does the same
thing, translating your name into a reference by lookup in the
package symbol table [which is held in a special hash].

OOP lends itself to nice expansion in the future, eg you can 
maintain state across several function calls inside the package 
space [see the function call counter below - not using a global]

# OOP despatch by name example
use strict;

# Sample despatch using OOP
my @todo = ( 'SubThree', 'SubOne', 'SubThree', 'Whoops' );
my $subs = mySubs->new();
foreach my $subname ( @todo ) {
  if ( $subs->can($subname) ) {
    $subs->$subname();
  } else {
    die "Don't know how to '$subname'";
  }
}

# Package that encapsualtes subs
# Can be USEd from a separate file called mySubs.pm
package mySubs;
use strict;
1;
# Constructor
sub new {
  my $ref   = shift;
  my $class = ref($ref) || $ref;
  my $self  = {
      _counter => 0,
    };
  bless $self, $class;
  $self->_initialise(@_);
  return $self;
}
# Initialisation
sub _initialise {
}
# Public Subs
sub SubOne {
  my $self = shift;
  $self->{_counter}++;
  print "SubOne() [Call $self->{_counter}]\n";
}
sub SubTwo {
  my $self = shift;
  $self->{_counter}++;
  print "SubTwo() [Call $self->{_counter}]\n";
}
sub SubThree {
  my $self = shift;
  $self->{_counter}++;
  print "SubThree() [Call $self->{_counter}]\n";
}


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to