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

Hi monks

Can anyone please explain to me the following error message

bash-2.05$ perl extract_seqs.pl main::check_gene() called too early to check prototype at extract_seqs +.pl line 22. main::check_gene_seq() called too early to check prototype at extract_ +seqs.pl line 27. main::extractseq() called too early to check prototype at extract_seqs +.pl line 32. syntax error at extract_seqs.pl line 106, near "$endpos) " Execution of extract_seqs.pl aborted due to compilation errors. bash-2.05$
With use of the code:
while (<INPUT>){ if ($_ =~ /\s{3}\<gene\sid\s\=\s\"(\d{1,6})\"\slabel\s\=\s\"([.|\. +]{1,40})\"\>/){ check_gene ($_); } if ($_ =~ /\s{4}\<gene_seq\sid\s\=\s\"(\d{0,6})\"\sstatus\s{0,2}\= +\s{0,2}\"(.{0,50})\"\s{0,2}CDS_number\s{0,2}\=\s{0,2}\"(\d{1,3})\"\s{ +0,2}number_of_CDSs\s{0,2}\=\s{0,2}\"(\d{0,5})\"\s{0,2}sequence_source +\s{0,2}\=\s{0,2}\"(.{0,300})\"\s{0,2}startpos\s{0,2}\=\s{0,2}\"(\d{0, +9})\"\s{0,2}endpos\s{0,2}\=\s{0,2}\"(\d{0,9})\"\s{0,2}startopen\s{0,2 +}\=\s{0,2}\"(\d{0,1})\"\sendopen\s{0,2}\=\s{0,2}\"(\d{0,1})\"\s{0,2}c +omplement\s{0,2}\=\s{0,2}\"(.{0,1})\"\>/){ check_gene_seq ($_); $label = "$gene_seq_id.$gene_seq_status.$gene_seq_CDS_number.$gene_se +q_number_of_CDSs.$gene_seq_sequence_source.$gene_seq_startpos.$gene_s +eq_endpos.$gene_seq_startopen.$gene_seq_endopen.$gene_seq_complement" +; } extractseq ($label,$gene_seq_sequence_source,$gene_seq_startpos,$g +ene_seq_endpos); }
In the context of
#!/usr/bin/perl -w ######### ### Programed 15_12_02_by Matthew Redden ######### #use strict; mkdir Output; $input = "new_out_again_12_12_02_B_hand_edit_15_12_02.txt"; open (INPUT, "<$input"); while (<INPUT>){ if ($_ =~ /\s{3}\<gene\sid\s\=\s\"(\d{1,6})\"\slabel\s\=\s\"([.|\. +]{1,40})\"\>/){ check_gene ($_); } if ($_ =~ /\s{4}\<gene_seq\sid\s\=\s\"(\d{0,6})\"\sstatus\s{0,2}\= +\s{0,2}\"(.{0,50})\"\s{0,2}CDS_number\s{0,2}\=\s{0,2}\"(\d{1,3})\"\s{ +0,2}number_of_CDSs\s{0,2}\=\s{0,2}\"(\d{0,5})\"\s{0,2}sequence_source +\s{0,2}\=\s{0,2}\"(.{0,300})\"\s{0,2}startpos\s{0,2}\=\s{0,2}\"(\d{0, +9})\"\s{0,2}endpos\s{0,2}\=\s{0,2}\"(\d{0,9})\"\s{0,2}startopen\s{0,2 +}\=\s{0,2}\"(\d{0,1})\"\sendopen\s{0,2}\=\s{0,2}\"(\d{0,1})\"\s{0,2}c +omplement\s{0,2}\=\s{0,2}\"(.{0,1})\"\>/){ check_gene_seq ($_); $label = "$gene_seq_id.$gene_seq_status.$gene_seq_CDS_number.$gene_se +q_number_of_CDSs.$gene_seq_sequence_source.$gene_seq_startpos.$gene_s +eq_endpos.$gene_seq_startopen.$gene_seq_endopen.$gene_seq_complement" +; } extractseq ($label,$gene_seq_sequence_source,$gene_seq_startpos,$g +ene_seq_endpos); } sub check_gene($) { # <gene id = "242" label = "SPCC576.16"> my $line = $_; if ($line =~ /\s{3}\<gene\sid\s\=\s\"(\d{1,6})\"\slabel\s\=\s\"([. +|\.]{1,40})\"\>/){ $gene_id = $1; $gene_label = $2; } else { print "ERROR. Somebody has altered the regular expression"; } return $gene_id; return $gene_label; } sub check_gene_seq($){ # <gene_seq id = "311" status = "Sanger source DNA code" CDS_number + = "3" number_of_CDSs = "" sequence_source = "" startpos = "2110545" +endpos = "2110823" startopen = "1" endopen = "1" complement = "C"/> if ($_ =~ /\s{4}\<gene_seq\sid\s\=\s\"(\d{0,6})\"\sstatus\s{0,2}\= +\s{0,2}\"(.{0,50})\"\s{0,2}CDS_number\s{0,2}\=\s{0,2}\"(\d{1,3})\"\s{ +0,2}number_of_CDSs\s{0,2}\=\s{0,2}\"(\d{0,5})\"\s{0,2}sequence_source +\s{0,2}\=\s{0,2}\"(.{0,300})\"\s{0,2}startpos\s{0,2}\=\s{0,2}\"(\d{0, +9})\"\s{0,2}endpos\s{0,2}\=\s{0,2}\"(\d{0,9})\"\s{0,2}startopen\s{0,2 +}\=\s{0,2}\"(\d{0,1})\"\sendopen\s{0,2}\=\s{0,2}\"(\d{0,1})\"\s{0,2}c +omplement\s{0,2}\=\s{0,2}\"(.{0,1})\"\>/){ my $gene_seq_id = $1; my $gene_seq_status = $2; my $gene_seq_CDS_number = $3; my $gene_seq_number_of_CDSs = $4; my $gene_seq_sequence_source = $5; my $gene_seq_startpos = $6; my $gene_seq_endpos = $7; my $gene_seq_startopen = $8; my $gene_seq_endopen = $9; my $gene_seq_complement = $10; } else { print "Error. Someone has altered the reguar expression"; } return $gene_seq_id; return $gene_seq_status; return $gene_seq_CDS_number; return $gene_seq_number_of_CDSs; return $gene_seq_sequence_source; return $gene_seq_startpoks; return $gene_seq_endpos; return $gene_seq_startopen; return $gene_seq_endopen; return $gene_seq_complement; } sub extractseq($$$$){ # Pass through the FASTA label, the location of +sequence, the start pos and the end pos. $label = $_[0]; $gene_seq_sequence_source = $_[1]; $startpos = $_[2]; $endpos) = $_[3]; print "$gene_seq_sequence_source\n"; sleep 1; print "system ('extractseq $gene_seq_sequence_source extracted_seq +_$label.txt -regions \"$startpos..$endpos\"')\;"; system ("extractseq $gene_seq_sequence_source extracted_seq_$label +.txt -regions \"$startpos..$endpos\""); }

Replies are listed 'Best First'.
Re: called too early to check prototype
by chromatic (Archbishop) on Dec 16, 2002 at 02:55 UTC

    According to the perldiag man page (if you add the line use diagnostics; to the top of your program, it'll print the relevant explanation when any error occurs), you're calling subroutines with prototypes before the program actually reaches the prototype declaration.

    What the other two posts say is correct -- you could either use a forward declaration at the top of your program to inform Perl about the prototypes, or you could call the subroutines with the leading ampersand to disable prototype checking.

    A better idea is to get rid of the prototypes, as you're not really taking advantage of them. For example, check_gene_seq() expects a single scalar as an argument, but you never use a passed-in argument. You're just lucking in to working with the magic global $_. (Further, your returns are broken and your if/else block is extremely broken.)

Re: called too early to check prototype
by batkins (Chaplain) on Dec 16, 2002 at 02:42 UTC
    My guess is that you're using the sub before you declare its prototype.

    Try putting:

    sub check_gene($); sub check_gene_seq($); sub extractseq($);

    at the top. Or you could just move the sub's above your main code.

Re: called too early to check prototype
by sauoq (Abbot) on Dec 16, 2002 at 05:43 UTC

    Short answer: Don't use prototypes at least until you understand why you shouldn't use them. This article by Tom Christiansen explains why they are usually more trouble than they are worth.

    Shorter answer: Don't call functions with prototypes prior to declaring them.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: called too early to check prototype
by pg (Canon) on Dec 16, 2002 at 02:46 UTC
    The solution provided in 1st reply is correct, and also there is another way to fix this problem: to put a '&' before those function calls, do something like:
    &func_abc($param_abc);
    I made a simple testing program, which has three parts:
    sub say_something($); #prototype sub say_something { #sub body print "I got ".shift()."\n"; } say_something("an apple");# call the sub.
    I played with it, with different sequences of the three parts(there are other combinations, you can play with them):
    1. proto->body->call, this fine.
    2. proto->call->body, this is also fine.
    3. call->proto->func, this is not fine, and got the error msg you got.
    4. call with &->proto->func, it back to okay.