5

我想做同样的事情

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”附近的操作员预期的位置找到字符串'

我该怎么办?

4

4 回答 4

6

打印手册页

如果您将句柄存储在数组或散列中,或者通常每当您使用比裸字句柄或普通的、未下标的标量变量更复杂的表达式来检索它时,您将不得不使用返回文件句柄值的块反而。

你应该使用:

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";
于 2012-01-30T14:25:37.663 回答
4

您应该改用 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() 类型调用编写了上述内容。)

于 2012-01-30T14:25:37.580 回答
0

文件句柄只能是标量。

但是$$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}行不通的。

于 2012-01-30T14:25:14.730 回答
0

这很容易通过为文件句柄创建一个变量来解决:

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
}
于 2012-01-30T15:48:11.977 回答