试图从perl函数返回一个哈希并且得到"不能使用字符串(" 0")作为HASH引用...."

时间:2014-05-26 20:46:12

标签: perl hash strict

我有一个Perl函数(名为readDicomFile),因此结束:

return { 'fileProperties' => \%fileProperties, 'filehandle' => *FH, 'buffersize' => $buffersize };

调用它的代码如下所示:

$file = readDicomFile( $ARGV[0] );
#use Data::Dumper;
#print Dumper $file;
my @imageData;
local *FH = $file->{filehandle};
while ( read(FH, $_, $file->{buffersize}) ) {
  push @imageData, unpack( 'S' x ( $file->{buffersize}/($file->{fileProperties}->{bitsAllocated}/8) ), $_ );
}
print "DEBUG: found ", (scalar @imageData), " elements\n";

我得到了这个输出:

Can't use string ("0") as a HASH ref while "strict refs" in use at ./test.pl line 17.
DEBUG: found 262156 elements

当我试图找出我的数据结构发生了什么时,我取消注释使用Data :: Dumper的两行,我得到了这个:

$VAR1 = {
          'fileProperties' => {
                                'echoNumber' => '',
                                'highBit' => 11,
                                'rows' => 512,
                                'bitsAllocated' => 16,
                                'modality' => 'CT',
                                'echoTime' => '',
                                'windowCenter' => '200',
                                'studyDescription' => 'CT SINUS / FACIAL WITH CONTRAST ',
                                'repetitionTime' => '',
                                'sequenceName' => '',
                                'method' => 'perl method',
                                'seriesNumber' => '502 ',
                                'imageNumber' => '0 ',
                                'windowWidth' => '50',
                                'trailer' => 0,
                                'pixelRepresentation' => 0,
                                'sliceLocation' => '',
                                'bitsStored' => 12,
                                'ultrasoundColorData' => '',
                                'rescaleIntercept' => 0,
                                'photometricInterpretation' => 'MONOCHROME2 ',
                                'description' => 'Patient Protocol',
                                'imageDataType' => '',
                                'imagePosition' => '',
                                'columns' => 512,
                                'studyDate' => '20140505'
                              },
          'filehandle' => *Radiology::Images::FH,
          'buffersize' => '1024'
        };

我已经使用了几种不同的习惯来从函数返回哈希值(比如传回哈希值或hashref),但我总是得到同样的错误。

有没有人能够洞察我的问题?

提前致谢。

编辑:

整个下午我一直在玩这个。这是当前test.pl

的全部内容
#!/usr/bin/perl -w
use lib '/etc/perl';
use strict;
use Radiology::Images;
my $file = $ARGV[0];
$file = readDicomFile( $file );
print STDERR "DEBUG: $file->{fileProperties}->{bitsAllocated}\n";
my @imageData;
# while ( $readsize = read ( $file->{filehandle}, $_, $file->{buffersize} ) ) {
#    push @imageData, unpack( 'S' x ( $file->{buffersize}/($file->{fileProperties}->{bitsAllocated}/8) ), $_ );
# }
my $readsize;
my $imagesize = $file->{fileProperties}->{columns} * $file->{fileProperties}->{rows};
print "DEBUG: should find $imagesize elements\n";
while ( $imagesize > 0 ) {
  $readsize = read ( $file->{filehandle}, $_, $file->{buffersize} );
  push @imageData, unpack( 'S' x ( $readsize/( $file->{fileProperties}->{bitsAllocated}/8 ) ), $_ );
  $imagesize -= $readsize /( $file->{fileProperties}->{bitsAllocated}/8 );
}
print "DEBUG: found ", (scalar @imageData), " elements\n";

...这给了我这个输出

DEBUG: 16
DEBUG: should find 262144 elements
Can't use string ("0") as a HASH ref while "strict refs" in use at /root/test.pl line 7.
DEBUG: found 262144 elements

...但是,当我将#15行中的'while'循环更改为

while ( $imagesize > 34816 ) {

我得到了这个输出:

DEBUG: 16
DEBUG: should find 262144 elements
DEBUG: found 227328 elements

所以,看起来我在第15行和第18行之间的循环中所做的事情会导致错误回到第7行。因此,我的问题从未过去了从我的函数返回哈希。 ??

顺便说一句,数字34816是通过实验到达的。 34816没有触发错误,34815没有。

鉴于这看起来非常糟糕,并且假设代码按照我认为的方式工作,尽管有错误,我想我只是假设它是一个语言错误并将我的注意力转向仅仅是压缩错误消息。

第二次编辑:

现在是test.pl:

#!/usr/bin/perl -w
use lib '/etc/perl';
use strict;
use Radiology::Images;
my $file = $ARGV[0];
$file = readDicomFile( $file );
my @imageData;
my $readsize;
while ( $readsize = read ( $file->{filehandle}, $_, $file->{buffersize} ) ) {
  push @imageData, unpack( 'S' x ( $readsize/($file->{fileProperties}->{bitsAllocated}/8) ), $_ );
}
print "DEBUG: found ", (scalar @imageData), " elements\n";

给了我这个输出:

Can't use string ("0") as a HASH ref while "strict refs" in use at /root/test.pl line 9.
DEBUG: found 5638203 elements

如果我注释掉'use strict'行,我会得到:

Use of uninitialized value in ref-to-glob cast at /root/test.pl line 9.
Use of uninitialized value in read at /root/test.pl line 9.
read() on unopened filehandle at /root/test.pl line 9.
DEBUG: found 5638215 elements

我,呃,显然......不明白这一点......

1 个答案:

答案 0 :(得分:1)

您需要返回对文件句柄的引用:

return {
    'fileProperties' => \%fileProperties,
    'filehandle'     => \*FH,              # <--- reference.
    'buffersize'     => $buffersize,
};

然后在阅读时,您可以直接在文件句柄上工作,您不必将其转移到fileglob:

# local *FH = $file->{filehandle};  <--- Not Needed. Below, just use the lexical fh
while ( read($file->{filehandle}, $_, $file->{buffersize}) ) {

如果从一开始就使用词法文件句柄,那么传递它们会变得更加明显:

open my $fh, '<', 'myfile.txt' or die "Can't open: $!";

return {
    'fileProperties' => \%fileProperties,
    'filehandle'     => $fh,
    'buffersize'     => $buffersize,
};