EpiMan
EpiMan

Reputation: 839

pass 3 value to sub : Too many arguments for

I have an input like this:

100 200 A_30:120,A_140:180,B_180:220
100 300 A_70:220,B_130:300,A_190:200,A_60:300

I want to count number of A or B in each line and also compare range of A or B in each line with the range in two first column and return the length of intersection. e.g. output for first line: A:2 A_length:40 B:1 B_length:20

while(<>){
chomp($_);
my @line = split("\t| ", $_);
my $col1 = $line[0];
my $col2 = $line[1];
my @col3 = split(",",$line[2]);
my $A=0;
my $B=0;
my $A_length=0;
my $B_length=0;
for my $i (0 .. @col3-1){
        my $col3 = $col3[$i];
        if ($col3 =~ /A/){
                my $length=0;
                $length = range ($col3,$col1,$col2);
                $A_length = $A_length+$length;
                $A++;
                    }
        if ($col3 =~ /B/){
                my $length=0;
                $length = range ($col3,$col1,$col2);
                $B_length = $B_length+$length;
                $B++;
                    }
                $i++;
}
                print("#A: ",$A,"\t","length_A: ",$A_length,"\t","#B: ",$B,"\t","length_B: ",$B_length,"\n");}




sub range {
                my ($col3, $col1, $col2)  = ($_[0],$_[1],$_[2]);
                my @sub = split(":|_", $col3);
                my $sub_strt = $sub[1];
                my $sub_end = $sub[2];
                my $sub_length;
                if (($col1 >= $sub_strt) && ($col2 >= $sub_end)){
                      $sub_length = ($sub_end) - ($col1);}
                if (($col1 >= $sub_strt) && ($col2 >= $sub_end)){
                      $sub_length = ($col2) - ($col1);}
                if(($col1 <= $sub_strt) && ($col2 >= $sub_end)){
                      $sub_length = ($sub_end) - ($sub_strt);}
                if(($col1 <= $sub_strt) && ($col2 <= $sub_end)){
                      $sub_length = ($col2) - ($sub_strt);}
                return $sub_length;
}

I FIXED IT :)

Upvotes: 0

Views: 228

Answers (1)

mob
mob

Reputation: 118665

Perl already has a builtin length function, which only takes one argument. As perl is compiling your script and gets to your length function call, it doesn't know about the sub length { ... } that you have defined later in the script, so it complains that you are using the builtin length function incorrectly.

How to fix this? This is Perl, so there are many ways

  1. name your function something else. Making a function with the same name as a Perl builtin function is usually a bad idea
  2. Call your function with the & sigil: my $length = &length($col3,$col1,$col2); That will be enough of a hint to the compiler that your function call does not refer to the builtin function.
  3. Qualify your function call with a package name, in this case main::length($col3,$col1,$col2) or just ::length($col3,$col1,$col2).

Note that even if Perl did know about the length function you defined (you could get Perl to know by moving the sub length { ... } definition to the top of the script, for example), the function call would still be ambiguous to the compiler, the compiler would emit a warning like

Ambiguous call resolved as CORE::length(), qualify as such or use & at ...

and your script would still fail to compile. Here CORE::length would mean that Perl is resolving the ambiguity in favor of the builtin function.

Upvotes: 4

Related Questions