我想做同样的事情
open MYFILE, ">", "data.txt";
print MYFILE "Bob\n";
而是在类变量中
sub _init_tmp_db
{
my ($self) = @_;
open $$self{tmp_db_fh}, ">", "data.txt";
print $$self{tmp_db_fh} "Bob\n";
}
它给了我这个错误:'在“Bob\n”附近的操作员预期的位置找到字符串'
我该怎么办?
我想做同样的事情
open MYFILE, ">", "data.txt";
print MYFILE "Bob\n";
而是在类变量中
sub _init_tmp_db
{
my ($self) = @_;
open $$self{tmp_db_fh}, ">", "data.txt";
print $$self{tmp_db_fh} "Bob\n";
}
它给了我这个错误:'在“Bob\n”附近的操作员预期的位置找到字符串'
我该怎么办?
从打印手册页:
如果您将句柄存储在数组或散列中,或者通常每当您使用比裸字句柄或普通的、未下标的标量变量更复杂的表达式来检索它时,您将不得不使用返回文件句柄值的块反而。
你应该使用:
print { $$self{tmp_db_fh} } "Bob\n";
此代码在use strict
. 要修复它,只需使用一个my
变量:
open my $fh, ">", "data.txt" or die $!;
$$self{tmp_db_fh} = $fh;
print { $$self{tmp_db_fh} } "Bob\n";
您应该改用 IO::File 模块。
use IO::File;
my $file = IO::File->new;
$file->open("> data.txt");
print_something($file);
sub print_something {
my ($file) = @_;
$file->print("hello world\n");
}
或者在您的示例函数中:
use IO::File;
# ...
sub _init_tmp_db
{
my ($self) = @_;
$self{tmp_db_fh} = IO::File->new;
$self{tmp_db_fh}->open(">", "data.txt");
$self{tmp_db_fh}->print"Bob\n";
}
(注意,你仍然可以不基于 -> 的调用,但我使用更传统的 ->open() 类型调用编写了上述内容。)
文件句柄只能是标量。
但是$$self{tmp_db_fh}
要么是打开的文件句柄(到 data.txt),那么这将起作用:
sub _init_tmp_db
{
my ($self) = @_;
my $filehandle = $$self{tmp_db_fh} ;
print $filehandle "Bob\n";
}
或者你打开里面的文件句柄_init_tmp_db
sub _init_tmp_db
{
my ($self) = @_;
open my $filehandle , ">", "data.txt" or die "Cannot open data.txt" ;
print $filehandle "Bob\n";
}
但是在(如'FILEHANDLE')中提供一个字符串是$$self{tmp_db_fh}
行不通的。
这很容易通过为文件句柄创建一个变量来解决:
sub _init_tmp_db {
my $self = shift;
my $fh;
open $fh, ">", "data.txt"
$self->{temp_db_fh} = $fh;
# Sometime later...
$fh = $self-{temp_db_hf};
print $fh "Bob\n";
}
这是一个问题,因为print
语法的解析方式和早期的语法草率。该print
语句实际上有两种不同的格式: 格式 #1 是您只是将内容传递给打印。格式 #2 表示第一项可能是文件句柄,其余部分是您要打印到文件句柄的内容。如果print
不能轻易确定第一个参数是文件句柄,则失败。
如果您查看其他语言,他们将使用一个参数来传递文件句柄,也许还有要打印的东西。或者在面向对象的语言中,它们会为文件句柄参数重载>>
。它们看起来像这样:
print "This is my statement", file=file_handle;
或者
print "This is my statement" >> file_handle;
您也许可以修改语法以摆脱使用变量。但是,它不会使程序更高效或更具可读性,并且可能只会使程序更难维护。因此,只需为文件句柄使用一个变量。
你在你的标题中说类。我假设您有兴趣编写一个完全成熟的面向对象的包来执行此操作。这是一个简单的例子。请注意,在write
子例程 方法中,我将文件句柄检索到一个变量中并在print
语句中使用该变量。
#! /usr/bin/env perl
#
use strict;
use warnings;
#######################################################
# MAIN PROGRAM
#
my $file = File->new;
$file->open("OUTPUT") or
die "Can't open 'OUTPUT' for writing\n";
$file->write("This is a test");
#
#######################################################
package File;
use Carp;
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
return $self;
}
sub open {
my $self = shift;
my $file = shift;
my $fh;
if (defined $file) {
$self->{FILE} = $file;
open ($fh, ">", $file) and $self->_fh($fh);
}
return $self->_fh;
}
sub _fh {
my $self = shift;
my $fh = shift;
if (defined $fh) {
$self->{FH} = $fh;
}
return $self->{FH};
}
sub write {
my $self = shift;
my $note = shift;
my $fh = $self->_fh;
print $fh $note . "\n";
return
}