从模块访问主程序中定义的文件句柄 [英] Accessing from modules a filehandle defined in main program

查看:157
本文介绍了从模块访问主程序中定义的文件句柄的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Perl中有以下有关文件处理程序访问的查询.

I have following query in Perl regarding the accessing of file handlers.

请考虑以下代码段,其中描述了确切的情况.

Consider the following code snippet which describes the exact scenario.

#!/usr/bin/perl -w
use warnings;
use strict;
use strict 'refs';

use File::Basename;
use Fcntl ':flock';

use feature qw/say switch/;

use File::Spec::Functions;
use File::Find;

require( "/home/rxa3kor/Mastering_Perl/sample.pm" );

our $LOGFILE = "sample";
open( LOGFILE, ">$LOGFILE" ) or die "__ERROR: can't open file\n'", $LOGFILE, "'!\n";
flock( LOGFILE, LOCK_EX );
print LOGFILE ( "Tool Start\n" );

&sample::func();

flock( LOGFILE, LOCK_UN );
close( LOGFILE );

sample.pm

#!/usr/bin/perl -w
package sample;

sub func() {
    print $main::LOGFILE ( "Printing in subroutine\n" );
}

当我执行上述代码片段时,出现以下错误.

when I execute the above said code snippet I am getting the following error.

在/home/rxa3kor/Mastering_Perl/sample.pm第6行上,未打开的文件句柄上的

print().

print() on unopened filehandle Mastering at /home/rxa3kor/Mastering_Perl/sample.pm line 6.

错误是因为文件手柄LOGFILEsample.pm模块下不可见.

Th error is because the filehandle LOGFILE is not visible under sample.pm module.

如何实现这个概念?

我想在Main.pl中打开一个文件,并且需要在不同的Perl模块中可以访问该文件句柄.

I want to open a file in Main.pl and I need this file handle to be accessible in different Perl modules.

推荐答案

您已经从Dave Cross获得了非常详细的分析一个>.

You've got an extremely detailed analysis from Dave Cross.

在这里,我想提供一种为所有要写入的模块提供干净的日志文件的方法.

Here I'd like to offer a way to cleanly provide a log file for all modules to write to.

介绍一个模块,该模块对子目录中的日志文件执行写操作;由需要此功能的所有模块加载.在该子目录中,使用 state 文件句柄打开要附加的日志文件,从而在通话中保持打开状态.然后,模块通过调用此子程序进行写操作,这可以通过main的调用来启动.

Introduce a module that performs the writes to a log file in a sub; load it by all modules that need that. In that sub open the log file to append, using state filehandle which thus stays open across the calls. Then the modules write by invoking this sub, and this can be initiated by a call from main.

记录器模块

package LogAll;

use warnings;
use strict;
use feature qw(say state);
use Carp qw(croak);    
use Exporter qw(import);

our @EXPORT_OK = qw(write_log);

sub write_log {
    state $fh = do {               # initialize; stays open across calls
        my $log = 'LOG_FILE.txt';
        open my $afh, '>>', $log or croak "Can't open $log: $!";
        $afh;
    };  
    say $fh $_ for @_;
}
1;

此示例中需要登录的其他两个模块实际上是相同的;这是一个

Two other modules, that need to log, are virtually the same for this example; here is one

package Mod1;

use warnings;
use strict;

use Exporter qw(import);    
use LogAll qw(write_log);

our @EXPORT_OK = qw(f1);

sub f1 {
    write_log(__PACKAGE__ . ": @_");
}
1;

主要

use warnings;
use strict;

use LogAll qw(write_log);    
use Mod1 qw(f1);
use Mod2 qw(f2);

write_log('START');

f1("hi from " . __PACKAGE__);
f2("another " . __PACKAGE__);

运行将导致文件LOG_FILE.txt


START
Mod1: hi from main
Mod2: another main

我为演示打印了START,但是不必从main中打开文件.

I print START for a demo but the file does not have to be opened from main.

请根据需要进一步开发打印机模块.例如,添加一种可选的文件名传递方式,以便main可以命名日志(通过改变类型和参数数量),并添加一种可控制地关闭日志的方式.

Please develop the printer module further as suitable. For example, add a way for the file name to be passed optionally so that main can name the log (by varying type and number of arguments), and add a way to close the log controllably.

这篇关于从模块访问主程序中定义的文件句柄的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆