尝试从perl函数返回散列并获取;can';t使用字符串(“0”)作为散列引用…”;

尝试从perl函数返回散列并获取;can';t使用字符串(“0”)作为散列引用…”;,perl,hash,strict,Perl,Hash,Strict,我有一个Perl函数(名为readDicomFile),它的结尾是: return { 'fileProperties' => \%fileProperties, 'filehandle' => *FH, 'buffersize' => $buffersize }; 调用它的代码如下所示: $file = readDicomFile( $ARGV[0] ); #use Data::Dumper; #print Dumper $file; my @imageData; loca

我有一个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
DEBUG: 16
DEBUG: should find 262144 elements
DEBUG: found 227328 elements
Can't use string ("0") as a HASH ref while "strict refs" in use at /root/test.pl line 9.
DEBUG: found 5638203 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”循环更改为

我得到这个输出:

Can't use string ("0") as a HASH ref while "strict refs" in use at ./test.pl line 17.
DEBUG: found 262156 elements
DEBUG: 16
DEBUG: should find 262144 elements
DEBUG: found 227328 elements
Can't use string ("0") as a HASH ref while "strict refs" in use at /root/test.pl line 9.
DEBUG: found 5638203 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 ./test.pl line 17.
DEBUG: found 262156 elements
DEBUG: 16
DEBUG: should find 262144 elements
DEBUG: found 227328 elements
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 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

一、 嗯,显然…不明白这一点….

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

return {
    'fileProperties' => \%fileProperties,
    'filehandle'     => \*FH,              # <--- reference.
    'buffersize'     => $buffersize,
};
返回{
“fileProperties”=>\%fileProperties,
'filehandle'=>\*FH,\$buffersize,
};
然后在读取时,您可以直接处理filehandle,而不必将其传输到fileglob:

# local *FH = $file->{filehandle};  <--- Not Needed. Below, just use the lexical fh
while ( read($file->{filehandle}, $_, $file->{buffersize}) ) {
#local*FH=$file->{filehandle};{filehandle},$\u,$file->{buffersize}){
如果从一开始就使用词法文件句柄,那么如何传递它们就变得非常明显:

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

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

打开我的$fh,'使用glob而不是globref不会导致OP看到的错误。我尝试了这一点,它的工作原理与我的原始代码完全相同。不过,谢谢。第17行是什么?readDicomFile是什么?是您运行test.pl的脚本还是您在这个脚本中运行test.pl?(尽管Miller建议使用词法文件句柄,但您显示的所有代码都应该按原样工作)readDicomFile是包含“return”语句的函数。test.pl是我用来验证函数输出的一个简短程序。@BrysonBorg第17行是什么?@Miller:我用附加信息更新了我的问题。结果表明,错误消息给出的行号是使用$file hashref的任何行,但riggers该错误是稍后在从$file->{filehandle}.Wierd读取的任何循环中发生的。@Miller:For context:&readDicomFile是读取dicom文件的函数(医学成像)。这些文件中的数据有效负载格式存在很多异构性,因此&readDicomFile分叉,子文件写入标准化数据(无符号,每像素2字节)将元数据和文件句柄传递回应用程序。考虑到这一点,对错误进行模块化,一切似乎都正常工作,我最终将对hashref的访问包装在一个eval{};中,以抑制服务器日志中的错误。这不是我喜欢的方式,而是我能想到的最佳方式。