Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Calling a subroutine within a conditional

by Freezer (Sexton)
on Sep 03, 2012 at 12:23 UTC ( #991416=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks,

I am looking to call a couple of subroutines within a conditional. Something like:
my $starting_point; my $continue_tag = "TRUE"; while ($continue_tag == "TRUE"){ look_through_file ($starting_point, $continue_tag); create_output (@array_of_lines, $entry_no_new); }
However I get the following error message:
main::look_through_file() called too early to check prototype at recei line 47.
Basically the $continue_tag may switch to 'FALSE' within the subroutine. At which point I was hoping that the subroutine would no longer be called. Have I made an obvious error in my assumptions?

Replies are listed 'Best First'.
Re: Calling a subroutine within a conditional
by Athanasius (Archbishop) on Sep 03, 2012 at 12:50 UTC

    The message you are seeing is a warning. It arises only if you have look_through_file declared with a prototype; for example:

    sub look_through_file($$) { ...

    There are three ways to deal with this:

    1. Move the definition of sub look_through_file to before the code where it is called (the while loop) — as recommended by daxim, above.
    2. Leave the definition where it is, but add a declaration before the calling code:
      sub look_through_file($$);
    3. Omit the prototype altogether. Unless you have a really good reason for including it, a prototype is usually a bad idea anyway.

    See Prototypes. Hope that helps,

    Athanasius <°(((><contra mundum

Re: Calling a subroutine within a conditional
by GrandFather (Saint) on Sep 04, 2012 at 00:35 UTC

    There look to be a bunch of things there that will make the code hard to understand and maintain.

    First off, don't use prototypes. That is your immediate problem as has already been suggested. They don't do what you think and cause subtle trouble that can lead to really hard to debug errors.

    Don't use artificial boolean values. Just accept that $continue_tag is a boolean variable that is false if it is empty or 0 and true otherwise.

    Make it clear where information comes from. You don't show @array_of_lines (bad name btw, why not just @lines?) being assigned any content. It's not clear how the work look_through_file does relates to the work create_output does. Where does $continue_tag's value get changed?

    Without any idea what your intent for the code is I can only sketch a better structure, but consider:

    #!/usr/bin/perl use strict; use warnings; my $fName = 'wibble.dat'; my $group; open my $fIn, '<', $fName or die "Can't open $fName: $!\n"; while (my @lines = scanFile($fIn)) { report(++$group, @lines); } sub scanFile { my ($fIn) = @_; my @lines; while (@lines < 10 && defined (my $line = <$fIn>)) { chomp $line; next if ! length $line; push @lines, $line; } return @lines; } sub report { my ($group, @lines) = @_; printf "%04d: %s\n", $group for @lines; }

    which batches lines from a file into groups of 10 non-blank lines then prints each group with a group prefix.

    True laziness is hard work
      I appreciate the code, however some of the commands and methods used are a bit advanced for me.

      My code currently stands as:

        Ask about the stuff you don't understand, but don't get distracted by peripheral stuff from the main point of the code: make the flow of information obvious.

        True laziness is hard work
Re: Calling a subroutine within a conditional
by borisz (Canon) on Sep 03, 2012 at 12:32 UTC
    "TRUE" is a string. You should use $continue_tag eq "TRUE" to compare strings.
      I fixed that, but still get:
      main::look_through_file() called too early to check prototype at recei line 47. main::create_output() called too early to check prototype at receive_a line 48.
        Where do you define the subroutines? If they are in the same package, move them above the main part of the code; that's better style anyway.
Re: Calling a subroutine within a conditional
by fullermd (Priest) on Sep 03, 2012 at 17:50 UTC

    Peripheral to the actual question, do you really want to use the strings "TRUE" and "FALSE"? Normally it's easier and more idiomatic to just use values like (numeric) '1' and '0'. If this interfaces with something external that really wants the strings, it can be cleaner to just convert at the interface between the two.

    Or not, of course. Circumstances do alter cases. But as a rule...

      I will convert to 1 and 0. I used "TRUE" and "FALSE" for clarity at this moment in time, just as an aid to help me understand my own code.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://991416]
Approved by Athanasius
Front-paged by ww
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (7)
As of 2021-10-22 10:56 GMT
Find Nodes?
    Voting Booth?
    My first memorable Perl project was:

    Results (85 votes). Check out past polls.