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

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

Hi all,

After working with R and other languages I have to do some work in Perl and it's giving me a headache.. I pass 3 parameters to my subroutine. Depending on the variable the script can change their value and the final section prints a custom XML script. But no matter what, the script will not work because of the local/global variables. How can I use the variable within a loop only when the 'if' condition is met and if not then use the pre-defined one?</p)

sub ddd { a = $_[0]; b = $_[1]; c = $_[2]; if ($a == '1') { $a = 'p'; } elsif ($a = '2') { $a = 'pp'; } if ($b == '3') { $b = 'w'} print v " < $a > < $b > < $c >"; }

Probably not the most elegant code but since there is so many variables I cannot make too many loops and start adding more variables as the code will grow too much. Any other way to do it?

Thanks for all your help.

Tom

Replies are listed 'Best First'.
Re: Loops and variable usage
by Eliya (Vicar) on Mar 23, 2012 at 18:34 UTC

    I don't see any loop, but I do see a couple of things which most likely don't do what you intended.  Maybe retry with this:

    sub ddd { my $a = $_[0]; my $b = $_[1]; my $c = $_[2]; # could also be written as: # my ($a, $b, $c) = @_; if ($a == 1) { $a = 'p'; } elsif ($a == 2) { $a = 'pp'; } if ($b == 3) { $b = 'w'} print " < $a > < $b > < $c >"; }
      Sorry, the loop is on upper level I tried to make it simpler. I have tried different combinations with my and none worked. for example $a is always 'p' even if the $_[0] was '2'. the loop is feeding the subroutine the proper values.
Re: Loops and variable usage
by apprentice (Scribe) on Mar 23, 2012 at 18:44 UTC
    First, you have bad syntax in your elsif conditional, a single = which assigns $a the value of 2. It should be ==.

    I reformatted your code to be more readable, fixed the ==, added 'my' to the subroutine vars, removed the 'v' filehandle so I could just print to the screen, seems to work for me based on your logic. Here is the code (always 'use strict;'!).

    #!/usr/bin/perl -w use strict; $| = 1; my $a = 1; my $b = 1; my $c = 1; print "Passing in \$a: $a, \$b: $b, \$c: $c: expect p 1 1\n"; ddd($a,$b,$c); $a = 2; $b = 2; $c = 2; print "Passing in \$a: $a, \$b: $b, \$c: $c: expect pp 2 2\n"; ddd($a,$b,$c); $a = 3; $b = 3; $c = 3; print "Passing in \$a: $a, \$b: $b, \$c: $c: expect 3 w 3\n"; ddd($a,$b,$c); sub ddd { my $a = $_[0]; my $b = $_[1]; my $c = $_[2]; if ($a == '1') { $a = 'p'; } elsif ($a == '2') { $a = 'pp'; } if ($b == '3') { $b = 'w' } print " < $a > < $b > < $c > \n"; }
    and here is the output:
    #> ./test-subroutine.pl Passing in $a: 1, $b: 1, $c: 1: expect p 1 1 < p > < 1 > < 1 > Passing in $a: 2, $b: 2, $c: 2: expect pp 2 2 < pp > < 2 > < 2 > Passing in $a: 3, $b: 3, $c: 3: expect 3 w 3 < 3 > < w > < 3 > #>


    "Peace, love, and Perl...well, okay, mostly just Perl!" --me

    Apprentice
      This script was just an example not proper code, but thanks very much for all help. I just figured out that I used '==' to compare strings...

        Actually, you use 'eq' for strings and '==' for numbers.

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.

Re: Loops and variable usage
by tobyink (Canon) on Mar 23, 2012 at 22:34 UTC

    Do not use variables named $a and $b.

    Perl has predefined variables named $a and $b which are used for sort. It is possible to use them for other purposes (List::Util does), but only via a lot of careful thought (or a lot of luck).

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Loops and variable usage
by JavaFan (Canon) on Mar 23, 2012 at 19:18 UTC
    It seems like your code is equivalent to:
    sub ddd { my $a = $_[0] == 1 ? 'p' : $_[0] == 2 ? 'pp' : $_[0]; my $b = $_[1] == 3 ? 'w' : $_[1]; my $c = $_[2]; print v " < $a > < $b > < $c >"; }
    Having said that, I don't which problem you are trying to solve. I don't see any loops.
      I find nested ternaries are much clearer using the code layout suggested by the book "Perl Best Practices"
      sub ddd { # code # value my $a = $_[0] == 1 ? 'p' : $_[0] == 2 ? 'pp' : $_[0] ; my $b = $_[1] == 3 ? 'w' : $_[1] ; my $c = $_[2]; print v " < $a > < $b > < $c >"; }