我有一个以块的形式读取FASTA文本文件的子文件。
sub reader {
foreach my $line (<IN>) { # read line by line
chomp $line;
if ($line =~ m/^>/) { # if it's a title
&initiator($title, $seq) unless $firsttitle == 1;
$firsttitle = 0;
($title = $line) =~ s/^>//; # title without > at start
$seq = ''; # new seq
} else {
$seq = $seq . $line; # append seq lines
}
}
&initiator($title, $seq); # Do the thing for the last seq.
}
在几个循环的中间,调用&amp; initiator。我想在一个模块中使用它,我可以使用&#34;但用其他模块的其他子代替&amp; initiator。这些潜艇也需要有自己的输入。是否会像以下工作或是否有更优雅的解决方案?
use Reader qw(reader);
use Othersub qw(subroutine);
my @par = ('Mary', 'Lamb');
my %functions = (foo => \&Othersub::subroutine);
&reader($file_to_read, $functions{'foo'}($par[0], $par[1]));
注意:最终文件结构是Othersub.pm,Reader.pm和使用这两个模块的脚本。
答案 0 :(得分:1)
Perl允许您创建对事物的引用,包括子例程和数组。
如果你有不同的论点要通过,那么我建议你想通过数组引用而不是你正在做的事情这样做。有点像这样:
use strict;
use warnings;
sub variable_args {
my ( $code_ref, $array_ref ) = @_;
#dereference code ref;
#dereference array ref;
&$code_ref( @$array_ref, "optional", "extra", "arg" );
}
sub foo_func {
foreach (@_) {
print "Foo $_\n";
}
}
sub bar_func {
print "BAR: ", join( ":", @_ ), "\n";
}
#could inline the functions as anonymous subs. I would avoid doing that
#unless they're pretty short/clear.
my %functions = (
'foo' => \&foo_func,
'bar' => \&bar_func,
);
my %args_to_pass = (
'foo' => [ "Mary", "Lamb" ],
'bar' => [ "Some", "Fish", "Pie" ],
);
for my $thing ( "foo", "bar" ) {
variable_args( $functions{$thing}, $args_to_pass{$thing} );
}
注意 - 在上面的示例中,您调用了&initiator
。你不应该这样做。它是Perl 4中不推荐使用的语法,并且是多余的(在某些情况下可能会产生一些不良后果)。
但我建议这样做,而不是你的方式。你可以让它工作:
&reader($file_to_read, $functions{'foo'}($par[0], $par[1]));
但是当您尝试这样做时会发生什么事情(您可能)立即运行您的功能,并将其结果传递给reader
。
E.g:
variable_args ( &{$functions{'foo'}}("Mary", "Lamb"), ["more stuff"] );
不会工作,因为你正在运行&#39;它会立即发送,然后发送结果 - 无论子例程的结果是什么,它都会使你$code_ref
。
但是你可以创建一个匿名子,然后传递:
variable_args( sub {
&{ $functions{'foo'} }( "Special", "Argument", @_ )
},
$args_to_pass{'foo'} );
我会建议你在这一点上不必要地复杂化了:)
答案 1 :(得分:1)
据我所知,你想传递一个函数(reference)作为参数。 这样的事情对你有用
# Script
use Reader qw(reader);
use Othersub qw(subroutine);
my @par = .... ;
reader( $file_to_read , \&subroutine , @par);
# Reader.pm
sub reader {
my $file = shift;
my $initiator = shift;
my @par = @_;
...
$initiator->( $file , @par)
...
}
备注:在代码的最后一行,您没有将函数subroutine
传递给reader
,因为您可能有意愿;相反,你调用它并传递 soubroutine的结果,给定参数par 给读者。