2012-01-30 27 views
5

Tôi muốn làm điều tương tự nhưLàm cách nào để tôi sử dụng thuộc tính/biến của lớp làm tệp có tay in trong Perl?

open MYFILE, ">", "data.txt"; 
print MYFILE "Bob\n"; 

nhưng thay vì trong biến lớp học như

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

    open $$self{tmp_db_fh}, ">", "data.txt"; 
    print $$self{tmp_db_fh} "Bob\n"; 
} 

Nó đã cho tôi lỗi này: 'String tìm thấy nơi khai thác dự kiến ​​gần 'Bob \ n''

tôi nên làm gì?

Trả lời

6

Từ print manpage: xử lý

Nếu bạn đang lưu trữ trong một mảng hoặc băm, hay nói chung bất cứ khi nào bạn đang sử dụng bất kỳ biểu hiện phức tạp hơn một tay cầm bareword hoặc một đồng bằng, vô hướng unsubscripted biến để truy xuất nó, bạn sẽ phải sử dụng một khối trả lại giá trị tệp handhandle thay thế.

Bạn nên sử dụng:

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

Mã này sẽ không hoạt động dưới use strict. Để khắc phục, chỉ cần sử dụng biến số my:

open my $fh, ">", "data.txt" or die $!; 
$$self{tmp_db_fh} = $fh; 
print { $$self{tmp_db_fh} } "Bob\n"; 
+1

Điều này sẽ không hoạt động với 'sử dụng nghiêm ngặt' refs ';' – dgw

+0

Tôi đã tìm kiếm nhiều địa điểm nhưng chưa bao giờ có trang đó. Cảm ơn nhiều. –

0

Thủ công chỉ có thể là vô hướng.

Nhưng $$self{tmp_db_fh} hoặc là một filehandle mở (để data.txt) thì đây sẽ làm việc:

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

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

hoặc bạn mở filehandle bê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"; 
} 

Nhưng việc cung cấp một chuỗi trong $$self{tmp_db_fh} (như 'FILEHANDLE') sẽ không hoạt động.

4

Bạn nên IO :: Mô-đun tệp thay thế.

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"); 
} 

Hoặc trong ví dụ chức năng của bạ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"; 
} 

(lưu ý, bạn vẫn có thể không -> dựa cuộc gọi quá, nhưng tôi đã viết ở trên sử dụng truyền thống hơn -> open() gõ các cuộc gọi .)

+0

Thx cho gợi ý nhưng, ngay bây giờ, tất cả các tệp khác tôi mở trong phương pháp sử dụng mã hiện tại của tôi như trong câu hỏi. –

+0

Đó là ok, IO :: Mô-đun tập tin thực sự sẽ làm việc như vậy quá. IE, nó an toàn để làm 'mở ($ tự {tmp_db_fh},"> "," data.txt ")' và nó sẽ hoạt động tốt, một khi bạn đã tạo IO :: File handle. –

+0

Bạn không cần ** để sử dụng [IO :: File] (http://perldoc.perl.org/IO/File.html). Như thường lệ với Perl [TMTOWTDI] (http://en.wikipedia.org/wiki/TMTOWTDI). –

0

này có thể dễ dàng giải quyết bằng cách tạo ra một biến cho một tập tin xử lý:

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"; 
} 

Đây là một vấn đề bởi vì cách cú pháp print được phân tích cú pháp và sự sloppiness sớm của cú pháp. Câu lệnh print có hai định dạng riêng biệt: Định dạng # 1 là bạn chỉ đơn giản là truyền nội dung đó để in. Định dạng # 2 nói rằng mục đầu tiên có thể là một tập tin xử lý, và phần còn lại là những thứ bạn muốn in vào tập tin xử lý. Nếu print không thể dễ dàng xác định rằng tham số đầu tiên là một tập tin xử lý, nó không thành công.

Nếu bạn nhìn vào các ngôn ngữ khác, họ sẽ sử dụng thông số để truyền xử lý tệp và có thể in nội dung. Hoặc trong các ngôn ngữ hướng đối tượng, chúng sẽ quá tải >> cho tham số xử lý tệp. Họ sẽ trông giống như thế này:

print "This is my statement", file=file_handle; 

hoặc

print "This is my statement" >> file_handle; 

Bạn có thể có thể munge cú pháp để tránh xa sử dụng một biến. Tuy nhiên, nó không làm cho chương trình hiệu quả hơn hoặc dễ đọc hơn, và có thể đơn giản làm cho chương trình khó duy trì hơn. Vì vậy, chỉ cần sử dụng một biến cho xử lý tập tin.


Bạn nói lớp trong tiêu đề của bạn. Tôi giả sử rằng bạn quan tâm đến việc viết một gói hướng đối tượng đầy đủ fledge để làm điều này. Đây là một ví dụ nhanh. Lưu ý trong phương thức write chương trình con Tôi truy xuất trình xử lý tệp thành một biến và sử dụng biến trong câu lệnh 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 
} 
Các vấn đề liên quan