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

From the print manpage:

If you're storing handles in an array or hash, or in general whenever you're using any expression more complex than a bareword handle or a plain, unsubscripted scalar variable to retrieve it, you will have to use a block returning the filehandle value instead.

You should be using:

print { $$self{tmp_db_fh} } "Bob\n";

This code won't work under use strict. To fix it just use a my variable:

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

これは、ファイル ハンドルの変数を作成することで簡単に解決できます。

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ステートメントには、実際には 2 つの異なる形式があります。フォーマット #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 に答える
0

Filehandles can only be scalars.

But $$self{tmp_db_fh} is either an open filehandle (to data.txt) then this would work:

sub _init_tmp_db
{
  my ($self) = @_;

  my $filehandle = $$self{tmp_db_fh} ;
  print $filehandle "Bob\n";
}

or you open the filehandle inside _init_tmp_db

sub _init_tmp_db
{
  my ($self) = @_;

  open my $filehandle , ">", "data.txt" or die "Cannot open data.txt" ;
  print $filehandle "Bob\n";
}

But providing a string in $$self{tmp_db_fh} (like 'FILEHANDLE') won't work.

于 2012-01-30T14:25:14.730 に答える