【发布时间】:2017-12-08 11:00:13
【问题描述】:
下面是我正在编写的模块的玩具版本。这个例子忠实地展示了我遇到的问题。
我有一个文件bed_in.txt
2L 0 4953
2L 16204 16284
2L 16612 16805
2L 17086 18561
2L 18757 18758
2L 19040 19120
2L 19445 19635
2L 19894 21366
2L 21582 21583
2L 47501 52365
2L 4698700 4709369
我想用来过滤数组中的值。
我想检查bed_in.txt的第二列是否匹配任何值
my @lines = qw/ 16204 40 200 149 19445 178 /;
如果是,则将 this 推送到数组。
我对这些数据的最终输出应该是@lines 中的两个元素,它们也在bed_in.txt 的第二列中
2L 0 4953
2L 16204 16284 # 16204 == 16204
2L 16612 16805
2L 17086 18561
2L 18757 18758
2L 19040 19120
2L 19445 19635 # 19445 == 19445
但是我应该在哪里打开我的文件?
这应该发生在调用我的模块run_fileOpen.pl 的脚本中,还是发生在模块本身中?
在任何一种情况下,我都没有得到正确的输出,而且我的模块似乎只为 @lines 的第一个元素调用
parseFile.pm
#!/usr/bin/perl
package parseFile;
use strict;
use warnings;
use FindBin qw/ $Bin /;
use lib File::Spec->catdir($FindBin::Bin, '..', 'bin/');
use Data::Printer;
open my $bed, '<', 'bed_in.txt';
sub check_lines {
my ($line, $filter_ref) = @_;
my @filter_reasons = @{ $filter_ref };
my $lines_to_filter_ref = filter_lines($line, $bed, \@filter_reasons);
return($lines_to_filter_ref);
}
sub filter_lines {
my ($line, $bed_file, $lines_to_filter) = @_;
my @filter = @{ $lines_to_filter };
while(<$bed_file>){
chomp;
my $start = (split)[1];
# print "line: $line start: $start\n";
if ($line == $start ) {
push @filter, "Filter as equal: $start, $line [$_]";
}
}
# p(@filter);
return(\@filter);
}
1;
run_parseFile.pl
#!/usr/bin/perl
use strict;
use warnings;
use parseFile;
my @lines = qw/ 16204 40 200 149 19445 178 /;
foreach(@lines){
my @filter_reasons = 'reason 1';
my $lines2filter = parseFile::check_lines($_, \@filter_reasons);
@filter_reasons = @{ $lines2filter };
print "$_\n" foreach @filter_reasons;
}
输出
reason 1
Filter as equal: 16204, 16204 [2L 16204 16284]
reason 1
reason 1
reason 1
reason 1
reason 1
当我在filter_lines 的while 循环中添加print 语句时,我可以看到只有第一个元素正在运行:
line: 16204 start: 0
line: 16204 start: 16204
line: 16204 start: 16612
line: 16204 start: 17086
line: 16204 start: 18757
line: 16204 start: 19040
line: 16204 start: 19445
line: 16204 start: 19894
line: 16204 start: 21582
line: 16204 start: 47501
line: 16204 start: 4698700
这是处理打开我的bed_in.txt 文件的合适方法,还是应该在run_parseFile.pl 脚本中打开它?或者我的代码还有其他完全错误的地方吗?
【问题讨论】:
-
bed_in.txt在现实中有多大? -
一个模块通常不应该打开一个静态路径的文件,这就是为什么它被称为模块。它应该可以在不同的上下文中使用。此外,它不应该在正文中打开文件(在编译时),但只能在调用方法/子例程时打开。否则它不是完全可测试的。
-
@Borodin 21154 行
-
您只看到一个检查值的原因是因为第一次调用
filter_lines会将文件读取到最后。随后的调用在 eof 处找到文件句柄,因此没有可读取的内容,并且永远不会再次执行while。你可以在filter_lines中打开文件来解决这个问题,但是如果总是有多个值要测试,那么效率非常低。无论如何,我倾向于把它做成一个面向对象的模块。 -
此代码所需的输出是什么?
Filter as equal输出只是调试代码吗?
标签: perl module file-handling