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

Code:
#!/usr/bin/perl -w use strict; my @array = (1, 2, 3, 4); my $string; my $item; foreach $item(@array) { &some_sub($item); } sub some_sub { if ($item = "1") { $string = "one"; } elsif ($item = "2" ) { $string = "two"; } elsif ($item = "3" ) { $string = "three"; } else { $string = "four" } print "My number is $string\n"; }
I have some serious problems here:

When run, it produces the output:
Found = in conditional, should be == at ./testsub.pl line 22. Found = in conditional, should be == at ./testsub.pl line 19. Found = in conditional, should be == at ./testsub.pl line 16. My number is one My number is one My number is one My number is one
When I change "=" to "==", I get:
Use of uninitialized value in numeric eq (==) at ./testsub.pl line 16. Use of uninitialized value in numeric eq (==) at ./testsub.pl line 16. Use of uninitialized value in numeric eq (==) at ./testsub.pl line 16. My number is four Use of uninitialized value in numeric eq (==) at ./testsub.pl line 16. Use of uninitialized value in numeric eq (==) at ./testsub.pl line 16. Use of uninitialized value in numeric eq (==) at ./testsub.pl line 16. My number is four Use of uninitialized value in numeric eq (==) at ./testsub.pl line 16. Use of uninitialized value in numeric eq (==) at ./testsub.pl line 16. Use of uninitialized value in numeric eq (==) at ./testsub.pl line 16. My number is four Use of uninitialized value in numeric eq (==) at ./testsub.pl line 16. Use of uninitialized value in numeric eq (==) at ./testsub.pl line 16. Use of uninitialized value in numeric eq (==) at ./testsub.pl line 16. My number is four
I suppose that I have two questions:

1. How can I assign a number to a variable?
2. How can I pass the array elements as args to a subroutine??

Replies are listed 'Best First'.
Re: Using array elements as subroutine args
by danger (Priest) on Feb 19, 2001 at 05:20 UTC

    You are passing the argument to the subroutine, but your subroutine is not using it (it is using the uninitialized $item from the file scope). When you pass parameters to a subroutine, those values will be available in the special @_ array within the subroutine. You need to either use the @_element directly ($_[0] in your case), or assign a copy of it to another variable. Try starting your subroutine like:

    sub some_sub { my $item = shift; my $string; # rest of subroutine }

    Just so you know: the shift() function, when not given an array to shift from will automatically shift from @_ inside of a subroutine, or @ARGV otherwise.

(dkubb) Re: (2) Using array elements as subroutine args
by dkubb (Deacon) on Feb 19, 2001 at 06:41 UTC

    Tuna, it is possible to do what you want using something called a dispatch table. It's simply a hash, where the key is what you are searching for, and the value is what you want if you find an exact match for the key. Below is your example re-worked to use a dispatch table:

    #!/usr/bin/perl -w use strict; my %number_to_word = ( 1 => 'one', 2 => 'two', 3 => 'three', ); my @numbers = qw(1 2 3 4); foreach my $number (@numbers) { print "My number is ", $number_to_word{$number} || 'four', "\n"; }

    Please note that if $number isn't a match in %number_to_word, we'll default to printing four, using the || operator. This neatly covers your else condition.

    One big advantage of using a dispatch table over an if/elsif/else statement is that it's much simpler to add and debug new conditions that you were aware of during the initial design.

    Also, if you're looking to translate numbers to words you might want to check out the CPAN module Lingua::EN::Nums2Words. It has a method called num2word which can translate any number you supply to it into the corresponding english word.

Re: Using array elements as subroutine args
by Coyote (Deacon) on Feb 19, 2001 at 05:15 UTC
    Try this:
    sub some_sub{ my $item = shift; #assign the first element of @_ to $item my ($string); if ($item == 1){ #note == not = or = = $string = 'one'; } if ($item == 2){ $string = 'two'; } # and so on ... print "My number is $string." }

    Checkout perlop and perlsub.

    ----
    Coyote

Re: Using array elements as subroutine args
by Tuna (Friar) on Feb 19, 2001 at 05:37 UTC
    Thanks Coyote and danger! I think I'm in the home stretch now!