我想在Perl对象中存储文件句柄。我就是这样做的。
sub openFiles {
my $self = shift;
open (my $itemsFile, "<", "items.txt") or die $!;
open (my $nameFile, "<", "FullNames.txt") or die $!;
$self->{itemsFile} = $itemsFile;
$self->{nameFile} = $nameFile;
return $self;
}
然后我想从其中一个文件中访问一些信息。我就是这样做的。
sub getItemDescription {
my $self = @_;
chomp(my $record = $self->{itemsFile});
return $record;
}
我尝试在另一个过程中访问它,如下所示:
print "Test 3: $self->getItemDescription()\n";
我的问题如下:
这对我来说非常重要。如果有任何方法可以改进我的代码结构,即为文件处理或更改对象的结构创建一个全局变量,请告诉我。
答案 0 :(得分:4)
是
没有。那只是分配文件句柄。一个人使用readline
运算符从文件中读取一行。
通常会使用<...>
运算符的readline
语法,但<...>
是readline(...)
和glob(qq<...>)
的快捷方式,Perl认为{ {1}}是<$self->{itemsFile}>
的缩写。您必须专门使用glob(qq<$self->{itemsFile}>)
readline
或做一些额外的工作
my $record = readline($self->{itemsFile});
chomp($record) if defined($record);
(请注意,我不会无条件地致电my $fh = $self->{itemsFile};
my $record = <$fh>;
chomp($record) if defined($record);
,因为chomp
/ readline
可以返回undef。)
我认为你的意思是返回字符串,就像<>
返回的字符串一样。问题是,你从来没有真正调用过该方法。 getItemDescription
在双引号字符串文字中没有任何意义,即使在变量之后也是如此。您需要将->getItemDescription()
移出双引号。
您也无法检查是否已到达文件的末尾。
答案 1 :(得分:2)
你很亲密。
要从文件句柄中读取记录(行),您可以在将文件句柄指定为“简单标量”之后使用内置readline
函数或<...>
运算符(请参阅下面的编辑)。 / p>
chomp(my $record = readline( $self->{itemsFile} );
my $fh = $self->{itemsFile};
chomp(my $record = <$fh>);
您的getItemDescription
方法中也存在错误。你想说
my ($self) = @_;
而不是
my $self = @_;
后一个调用是一个数组的标量赋值,它解析为数组的长度,而不是数组的第一个元素。
编辑:<$self->{itemsFile}>
和<{$self->{itemsFile}}>
不起作用,as perlop
explains:
如果尖括号内的内容既不是文件句柄也不是包含文件句柄名称,typeglob或typeglob引用的简单标量变量,则它被解释为要进行全局化的文件名模式,以及文件名列表或下一个文件名在列表中返回,具体取决于上下文。这种区别仅仅是出于句法原因而确定的。这意味着
<$x>
始终是间接句柄的readline()
,但<$hash{key}>
始终是glob()
。那是因为$x
是一个简单的标量变量,但$hash{key}
不是 - 它是一个哈希元素。即使<$x >
(请注意额外空格)也会被视为glob("$x ")
,而不是readline($x)
。
答案 2 :(得分:0)
openFiles
件是正确的。
错误主要发生在getItemDescription
方法。
首先,如前所述,my $self = @_;
应为my ($self) = @_;
。
然而,问题的关键在于以下列方式解决:
将chomp(my $record = $self->{itemsFile});
更改为两行:
$file1 = $self->{itemsFile};
chomp(my $record = $file1);
为了澄清你必须(根据我的经验,我尝试了所有建议的解决方案)使用标量值。
最后,请参阅ikagami答案中的最后两段。