http://www.perlmonks.org?node_id=555999

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

Hi Monks
#!/user/bin/perl -w upper($1,$2); sub upper { for(@_) { tr/a-z/A-Z/; } }
I am trying to modify the nameless farmal arguments to actual arguments ,the above code is giving an error as "modification to readonly value attempted".so,suggest me so,that i can trap my mistake.

Replies are listed 'Best First'.
Re: How to modify the actual arguments
by Zaxo (Archbishop) on Jun 17, 2006 at 19:01 UTC

    $1 and $2 are read-only, set internally by perl as a result of regex matching. If you call upper() on $foo and $bar, your function will do what you intend.

    You can guard against fatal errors by wrapping in eval{}. You can catch some such errors at compile time with the (\$) prototype, but that wouldn't catch an attempt to modify $1.

    Your function can be made more independent of language by writing it with uc,

    sub upper { eval { $_ = uc for @_; 1; } }

    After Compline,
    Zaxo

Re: How to modify the actual arguments
by GrandFather (Saint) on Jun 17, 2006 at 19:07 UTC

    There is something you are not telling us.

    Update: your function is fine, it is your call that is the issue as Zaxo pointed out.

    use strict; use warnings; my $str1 = "This is string 1."; my $str2 = "String 2 this one is."; upper ($str1, $str2); print "$str1 $str2"; sub upper { tr/a-z/A-Z/ for @_; }

    Prints:

    THIS IS STRING 1. STRING 2 THIS ONE IS.

    DWIM is Perl's answer to Gödel
Re: How to modify the actual arguments
by sgifford (Prior) on Jun 17, 2006 at 19:44 UTC
    If that's your whole program, I suspect you mean $ARGV[0] and $ARGV[1], which refer to the command-line arguments to your program, and not $1 and $2, which refer to the last two captures from a regular expression match. Making that change, your program doesn't give an error.
      HI Monk, thankx for suggation,i am trying to modify the constants in this program,so,we can't use the subscript on constant items.