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

Monks,

Is there a way of avoiding the use of no strict 'refs' in the following code fragment. I know symbolic references are ugly, but the alternatives are probably worse. Is this one of those cases where no strict 'refs' is best?

sub AUTOLOAD { use vars qw($AUTOLOAD); my ($pkg,$method) = ($AUTOLOAD =~ /(.*)::(\w+)$/); my ($self,@args) = @_; my $pkgTmplt; my $pkgv = $pkg.'::_template'; { no strict 'refs'; $pkgTmplt = $$pkgv{$method}; } if ($pkgTmplt) { my $acc = $self->accessor($method,$pkgTmplt); my $chunk = <<END package $pkg; sub $method { $acc } END ; eval $chunk; die "Error making accessor: $@\nCode follows:\n$chunk" if $@; wantarray ? ($self->$method(@args)) : $self->$method(@args); } else { croak "Unknown sub $method in $pkg "; } }

Replies are listed 'Best First'.
Re: strict refs and package namespaces
by merlyn (Sage) on Feb 19, 2002 at 13:30 UTC
    I'm not sure why you're putting the work of selecting the template into the autoload. If you pushed the problem down into the "accessor" method, then you'd simply be passing the subroutine name to accessor, and it could chose to return $acc or undef, and for undef you croak. The accessor method could own the hash as a lexical variable to control the mapping.

    Also, you're working far too hard to install the $acc as a coderef in the current package. It's much easier to use a glob (warning untested code, but it's close to this):

    *{$pkg."::$method"} = eval "sub { $acc }";

    -- Randal L. Schwartz, Perl hacker

Re: strict refs and package namespaces
by broquaint (Abbot) on Feb 19, 2002 at 11:37 UTC
    This is indeed one of those cases where using no strict 'refs' is best. Of course I'm sure you can do this without having to turn off strict refs (check out Strict, strings and subroutines for some insights), this really is a very valid case to turn them off, as this is usually how most symbol table munging is done. Heck, the likes of Exporter.pm don't even use strict at all!
    HTH

    broquaint