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

I want my subroutine to calculate the tables of 2,3,4 and display them in separate lines.I made a subroutine called "table" and passed 2,3,4 as parameter.But I am getting the table of 2 only and not 3 and 4.Below is my code.Please check and let me know.

use strict; use warnings; use diagnostics; use 5.01000; &table(2,3,4); sub table{ my $i = 1; my $loop; foreach $loop(@_){ for($i;$i<=10;$i++){ my $ans = $i*$loop; print"$ans "; } print"\n"; } }

Replies are listed 'Best First'.
Re: Help me
by Anonymous Monk on Jan 15, 2012 at 09:41 UTC

    Hi, read this

    Tutorials: Debugging and Optimization: Basic debugging checklist

    Armed with that knowledge, I modify your program to

    use strict; use warnings; use diagnostics; use 5.01000; &table( 2, 3, 4 ); sub table { my $i = 1; my $loop; foreach $loop (@_) { warn " loop $loop \n"; for ( $i ; $i <= 10 ; $i++ ) { my $ans = $i * $loop; print "$ans "; } print "\n"; } } __END__

    And the output is

    loop 2 2 4 6 8 10 12 14 16 18 20 loop 3 loop 4

    So, what is happening is, it is looping over the arguments to the subroutine correctly, but the problem of printing the values, the problem with the inner loop is, the condition is false for some reason

    To see why the warn is now

    warn " loop $loop i $i \n";
    and the output
    loop 2 i 1 2 4 6 8 10 12 14 16 18 20 loop 3 i 11 loop 4 i 11

    So  for ( $i ; $i <= 10 ; $i++ ) { first executes  $i; , executed once, on the first run through the loop (loop initialization). It generates this warning Useless use of private variable in void context

    Then second part  $i <= 10; checks if 11 is greater than 10, so the loop doesn't execute

    Why? Because of scoping, read this

    Tutorials: Variable Scoping in Perl: the basics, Coping with Scoping

    If you move  my $i = 1; into the inner for loop like  for ( my $i = 1; $i <= 10 ; $i++ ) { it will work as you want

    2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40

    They call this c-style for loop. The perl-style for loop would be  for my $i ( 1 .. 10 ) {

    For learning this level of perlintro I liked http://learn.perl.org/books/beginning-perl/ book, its available as free pdf

    Hi, this being your 8th post and all, I've got a link for you :)

    PerlMonks FAQ: How do I compose an effective node title?

    I recognize that you're very new so it can be real hard to compose a title, but instead of "help me" you might include words you used in the question, words like: loop, sub, parameter, print

Re: Help me
by ansh batra (Friar) on Jan 15, 2012 at 09:32 UTC
    Thakur ji reinitialize $i after for loop
    i.e add $i=1; after for loop ,before closing of foreach loop
    and please put the effective title for you post
      Thanks Ansh bhai. I will take care of the title.
Re: subroutine to calculate multiplication tables
by CountZero (Bishop) on Jan 15, 2012 at 13:47 UTC
    Two remarks:
    1. don't put a & before your subroutine call. Most of the times it is unnecessary, it does things you are clearly not aware of (see perlsub) and unless you know the few cases you need it, just don't do it.
    2. You don't need $i (or $ans) at all. Make your inner loop as follows: print $_*$loop, ' ' for 1 .. 10;

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: subroutine to calculate multiplication tables
by Anonymous Monk on Jan 15, 2012 at 15:31 UTC
    As CountZero indicated, here's a working example:
    #!/usr/local/bin/perl use strict; use warnings; use diagnostics; use 5.01000; table( 2, 3, 4 ); sub table { foreach my $loop (@_) { print $_*$loop, ' ' for 1 .. 10; print "\n"; } }