我正在尝试实现一个计算输入字符串的d邻居的子程序。这是planted motif search的一个实现的一部分,但我的问题更为笼统。这是代码:
#subroutine for generating d-neighbors
sub generate_d_neighbors{
# $sequence is the sequence to generate d-neighbors from
# $HD is the Hamming Distance
my ($sequence, $HD) = @_;
for(my $i = 0; $i=$HD; $i++){
my @l = ['A', 'C', 'T', 'G'];
my @t = splice(@l,$sequence[$i]);
#TODO
}
}
错误发生在最后一行,说:
Global symbol "@sequence" requires explicit package name (did you forget to declare "my @sequence"?
据我所知,Perl不会像Java中那样采用subroutine(param1, param2)
形式的参数,但为什么$sequence
未被识别为已经初始化?
答案 0 :(得分:4)
您的代码存在一些问题:
sub generate_d_neighbors{
my ($sequence, $HD) = @_;
for(my $i = 0; $i=$HD; $i++){
my @l = ['A', 'C', 'T', 'G'];
my @t = splice(@l,$sequence[$i]);
}
}
首先,让我们看一下
for(my $i = 0; $i=$HD; $i++){
假设$HD
非零,此循环将永远不会终止,因为条件永远不会为假。如果您希望$i
的范围从0
到$HD
,那么将该语句写为for my $i (0 .. $HD)
会更好。
其次,你有
my @t = splice(@l,$sequence[$i]);
你似乎假设有一个数组@sequence
,你正试图访问它的第一个元素。但是,$sequence
是对数组的引用。因此,您应该使用
$sequence->[$i]
第三(感谢@Ikegami),你有
my @l = ['A', 'C', 'T', 'G'];
在for
循环中。然后@l
将包含单个元素,即对包含元素'A'
,'C'
,'T'
和'G'
的匿名数组的引用。相反,使用:
my @l = qw(A C T G);
我不确定您希望使用splice(@l, $sequence->[$i])
确切达到什么目标,但可以更好地编写为:
my @t = @l[0 .. ($sequence->[$i] - 1)];
实际上,您可以将两个分配减少到:
my @t = qw(A C T G)[0 .. ($sequence->[$i] - 1)];
答案 1 :(得分:0)
在我看来,你想要
substring($sequence, 0, 1)
而不是
$sequence[0].
在Perl中,字符串是第一类变量,而不是数组类型。
或许你想要splice(@l, $sequence->[0])
?
答案 2 :(得分:0)
此列表分配语法:
my (@sequence, $HD) = @_;
没有做你想做的事情(将最后一个参数放在$HD
中,其余参数放在@sequence
中)。数组总是占用它所能得到的所有参数,不会留下任何参数。
如果只有一个数组,则撤销订单可以正常工作:
my ($HD, @sequence) = @_;
并在调用者中进行相应的更改。
要更一般地解决问题,请使用参考:
my ($sequence, $HD) = @_;
并像这样调用sub:
generate_d_neighbors(\@foo, $bar);
或者这个:
# Note the brackets, which make an array reference, unlike parentheses
# which would result in a flat list.
generate_d_neighbors([...], 42);
如果您使用原型:
sub generate_d_neighbors (\@$)
然后调用者可以说
generate_d_neighbors(@foo, $bar);
并且@foo
自动成为引用,就好像它是\@foo
。
如果您使用任何基于参考的解决方案,则必须根据以下规则更改函数体以使用$sequence
而不是@sequence
:
@sequence
更改为@$sequence
$#sequence
更改为$#$sequence
$sequence[...]
更改为$sequence->[...]
@sequence[...]
更改为@$sequence[...]
(但请确保您真的打算使用数组切片...如果您对perl不熟悉,那么您可能并不意味着它,并且应该使用$sequence[...]
代替)