How about

use strict;

sub unstrict : lvalue
  {
    my $sym = shift;
    no strict 'refs';
    ${$sym};
  }

unstrict("a::b") = 1;

print "$a::b\n";

F

On 7/24/05, Tassilo von Parseval <[EMAIL PROTECTED]> wrote:
> On Sun, Jul 24, 2005 at 02:44:12AM -0400 Jeff 'japhy' Pinyan wrote:
> > That sounds sillier than my concern actually is.  I noticed today (I don't
> > know why today, and not the days before when I've seen this common idiom)
> > that a person creating dynamic functions did the following:
> >
> >   use strict;
> >
> >   # ...
> >
> >   for (@function_names) {
> >     no strict 'refs';
> >     *$_ = sub {
> >       # ...
> >     };
> >   }
> >
> > I've seen that in various perldocs, and it seems to be a common practice
> > when it comes to defining dynamically named functions.  But there's a very
> > specific flaw inherent here.
> >
> >   use strict;
> >
> >   my @method_names = qw( foobar quux xyzzy );
> >
> >   for my $m (@method_names) {
> >     no strict 'refs';
> >     *{ "ClassName::$m" } = sub {
> >       my ($self, $val) = @_;
> >       $self->{$m} = $val;
> >     };
> >   }
> >
> > This sets up a bunch of methods for some object of class ClassName.  The
> > idea being you can now say
> >
> >   my $obj = ClassName->new;
> >   $obj->foobar(10);
> >
> > and set $obj->{foobar} to 10.  But what if you slip up and write
> >
> >   ClassName->foobar(10);
> >
> > As Scooby-Doo would say, "RUH ROH!"  We turned off strict's grip on
> > references, and now we've accidentally worked with a symbolic reference.
> > And strict won't mind a bit!
> 
> Nice catch. It looks obvious enough, but yet it never occured to me. For
> more complicated methods generated thusly, you can now even mistype
> lexicals and no longer receive the compile-time error.
> 
> > Although it looks a bit clunkier, I would suggest changing the idiom to
> >
> >   for (...) {
> >     my $code = sub { ... };
> >     no strict 'refs';
> >     *$_ = $code;
> >   }
> 
> Or:
> 
>     for (...) {
>         no strict 'refs';
>         *$_ = sub {
>             use strict;
>             ...
>         };
>     }
> 
> which avoids the temporary '$code'. Also, careless authors might feel
> tempted to 'optimize' your code again into its original strictless form.
> 
> Tassilo
> --
> use bigint;
> $n=71423350343770280161397026330337371139054411854220053437565440;
> $m=-8,;;$_=$n&(0xff)<<$m,,$_>>=$m,,print+chr,,while(($m+=8)<=200);
> 
>

Reply via email to