Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^2: Strange behavior: passing $1 to AUTOLOAD

by johnnywang (Priest)
on Sep 22, 2004 at 22:33 UTC ( [id://393069]=note: print w/replies, xml ) Need Help??


in reply to Re: Strange behavior: passing $1 to AUTOLOAD
in thread Strange behavior: passing $1 to AUTOLOAD

Thanks. But what is the general rule here? a sub needs to always make a copy of the parameters if it uses regex?
  • Comment on Re^2: Strange behavior: passing $1 to AUTOLOAD

Replies are listed 'Best First'.
Re^3: Strange behavior: passing $1 to AUTOLOAD
by Elian (Parson) on Sep 22, 2004 at 22:50 UTC
    The general rule is never, ever pass in $1 and its friends, as they're terribly ephemeral. Make copies and pass them in instead.
      Make copies and pass them in instead.
      This is as easy as just passing "$1" instead of $1.
      The general rule is never, ever pass in $1 and its friends, as they're terribly ephemeral. Make copies and pass them in instead.
      That's a good general rule but I'd still go for belt and braces.

      If the API of a function doesn't say it treats its arguments as lvalues then it is good practice to make copies of the elements from @_. If you need to do any regex processing before you unpack @_ then wrap it in a block.

Re^3: Strange behavior: passing $1 to AUTOLOAD
by hv (Prior) on Sep 22, 2004 at 23:06 UTC

    As Elian says, make copies when passing in ephemeral values such as $1, $!, $@; one easy way to do that is to stringify, as long as that doesn't lose you information:

    $person->name("$1");

    If just the string is not enough (eg to pass the dualvar $!), I think the easiest way is to make a copy:

    my $error = $!; $log->error($error);

    Hugo

      Aha! But what if you don't want to create a lexical variable that lives any longer than necessary? Well, you could use a bare block:

      { my $error = $!; $log->error($error) }

      But then what if you want the return value from the method? Well, you could use do:

      my $return = do { my $error = $!; $log->error($error) };

      That's probably the sane way to handle it. But what if you're not sane? Then we can have some fun!

      my $return = $log->error(${ \(my $e = $!) });

      Update: another fun way that never even makes the lexical variable:

      my $return = $log->error(@{[$!]});
Re^3: Strange behavior: passing $1 to AUTOLOAD
by diotalevi (Canon) on Sep 22, 2004 at 22:51 UTC

    Function parameters are passed by reference. This means @_ contained $1 which is modified by any successful regex. You can modify values in @_ directly to watch this.

    Most of the time you aren't passing something like $1 in and don't have to worry about the issue you ran into

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://393069]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2024-04-20 02:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found