[Chicago-talk] logging in and out files
Alexander Danel
danel at speakeasy.net
Tue Oct 26 10:39:10 PDT 2010
Brian - yep, I jumped in without any context.
Tiger - the code below illustrates the problem, and a solution.
Firstly, note that the situation you are encountering seems to match with
the documentation, as correct and expected behavior. Here is the URL to
"perldoc.org":
http://perldoc.perl.org/functions/open.html
And here is an excerpt from the first paragraph:
. . . otherwise if FILEHANDLE is an expression, its value is used as the
name of the real filehandle wanted. (This is considered a symbolic
reference, so use strict 'refs' should not be in effect.)
Secondly, based on my tests just now, it seems "strict" is making a special
exception for file based operations. That would explain why we routinely
use a naked string in an open, without getting it flagged. So, "strict"
seems to make an exception for:
open FH, 'someFile.txt";
In the sample code, the following is not allowed by "strict"; I assume this
illustrates the problem you are having.
myLog::open(FH2,'someFile.txt');
However, in the sample code, I was able to alias the original symbol
"open()" in "main"; in other words, I aliased "main::open()". In that case,
"strict" applies the (apparent) special handling.
# Alias
*open = \&myLog::open;
open(FH3,'someFile.txt');
So, that is your solution.
Note - in the sample code you will also see an attempt to use the "Exporter"
module. That didn't work; it seems that "Exporter" also makes a special
case of "open()" - it refused to export it. (That code is commented out,
the "__DATA__" directive.)
Code appears below. Have fun.
Alexander Danel
#!/usr/bin/perl
my $fName = "t.pl";
my $fMode = "<";
package myLog;
sub open{
use Cwd;
my ($package, $file, $line_number) = caller();
my $fullpath = Cwd::abs_path($file);
if ($_[0]) {
no strict 'refs';
CORE::open("::$_[0]", $_[1]) or die "Cannot open $_[1]: $!\n";
} else {
CORE::open($_[0], $_[1]) or die "Cannot open $_[1]: $!\n";
}
}
package main;
use strict;
open(FH1,"$fMode $fName");
print "Here is first line of FH1: ", scalar(<FH1>), "\n";
close(FH1);
# Uncomment the following code to see the problem -- "strict" will flag it.
#myLog::open(FH2,"$fMode $fName");
#print "Here is first line of FH2: ", scalar(<FH2>), "\n";
#close(FH2);
# Alias
*open = \&myLog::open;
open(FH3,"$fMode $fName");
print "Here is first line of FH3: ", scalar(<FH3>), "\n";
close(FH3);
__DATA__
package myLogExported;
use Exporter 'open()' ;
sub open{
use Cwd;
my ($package, $file, $line_number) = caller();
my $fullpath = Cwd::abs_path($file);
if ($_[0]) {
#no strict 'refs';
CORE::open("::$_[0]", $_[1]) or die "Cannot open $_[1]: $!\n";
} else {
CORE::open($_[0], $_[1]) or die "Cannot open $_[1]: $!\n";
}
}
package main;
use strict;
open(FH4,"$fMode $fName");
print "Here is first line of FH4: ", scalar(<FH4>), "\n";
close(FH4);
_____
From: chicago-talk-bounces+danel=speakeasy.net at pm.org
[mailto:chicago-talk-bounces+danel=speakeasy.net at pm.org] On Behalf Of tiger
peng
Sent: Monday, October 25, 2010 2:30 PM
To: Chicago.pm chatter
Subject: Re: [Chicago-talk] logging in and out files
Alex,
I am trying create a module, say myLog.pm, to override the built-in open
function, adding auxiliary abilities (logging the file access information).
I am looking for minor modification, adding one line "use myLog 'open';' in
a hundreds of scripts. The developing module works for the scripts without
using typeglob filehandle (open FH, $filename); if no using "use stricts",
it also works for the typeglob filehandle.
It seems after overriding, the compiler take the 'FH' in the open function
as calling a subroutine.
Tiger,
_____
From: Alexander Danel <danel at speakeasy.net>
To: Chicago.pm chatter <chicago-talk at pm.org>
Sent: Mon, October 25, 2010 3:10:10 PM
Subject: Re: [Chicago-talk] logging in and out files
Tiger,
Firstly, I noticed you named your function "open()" - I wouldn't use that
name, it is the name of a Perl operator; In fact, you use Perl "open()"
within your "open()".
Secondly, the error message might be indicating a simple syntax error in
preceding code. Look for a missing semi-colon, etc., in the code just
before the error.
Alexander Danel
_____
From: chicago-talk-bounces+danel=speakeasy.net at pm.org
[mailto:chicago-talk-bounces+danel=speakeasy.net at pm.org] On Behalf Of tiger
peng
Sent: Monday, October 25, 2010 12:24 PM
To: Chicago.pm chatter
Subject: Re: [Chicago-talk] logging in and out files
Weird, when I tested the module, with open FH, $filename; with use strict;
It complain with message: Bareword "FH" not allowed while "strict subs" in
use...
_____
From: tiger peng <tigerpeng2001 at yahoo.com>
To: Chicago.pm chatter <chicago-talk at pm.org>
Sent: Fri, October 22, 2010 2:11:07 PM
Subject: Re: [Chicago-talk] logging in and out files
I tried out a working version below. It works for $FH and FH, but not clear
why.
sub open{
my ($package, $file, $line_number) = caller();
my $fullpath = Cwd::abs_path($file);
my $host = hostname();
_open_log({host=>hostname(),
script=>Cwd::abs_path($file),
file=>$_[1],
}
);
if ($_[0]) {
no strict 'refs';
CORE::open("::$_[0]", $_[1]) or die "Cannot open $_[1]: $!\n";
} else {
CORE::open($_[0], $_[1]) or die "Cannot open $_[1]: $!\n";
}
}
_____
From: imran javaid <imranjj at gmail.com>
To: Chicago.pm chatter <chicago-talk at pm.org>
Sent: Thu, October 21, 2010 2:46:29 PM
Subject: Re: [Chicago-talk] logging in and out files
This might get you somewhere:
use strict;
use Symbol;
sub myopen {
if (ref(\$_[0]) eq 'SCALAR') {
open ($_[0], $_[1]);
} else {
my $in = qualify_to_ref($_[0]);
open($in, $_[1]);
}
}
myopen(*FILE, ">file.txt") or die $!;
print FILE "testing\n";
myopen(my $FILE2, ">file2.txt") or die $!;
print $FILE2 "testing2\n";
If you remove "use strict;" then you can replace "*FILE" with "FILE",
but can and should are not the same thing.
-imran
On Thu, Oct 21, 2010 at 12:34 PM, tiger peng <tigerpeng2001 at yahoo.com>
wrote:
> Thanks, it looks a good tool and I will try it later.
>
> But my problem now is how to pass in and back the FH.
>
> It complains with error message:
> Can't use string ("FH") as a symbol ref while "strict refs" in use at
> /my/lib/myLogger.pm ...
>
> When I let it do not complain with "no strict 'refs';", it does not
complain
> but FH seems not opened or not passed back, as the caller read nothing
out.
>
> ________________________________
> From: Joshua <joshua.mcadams at gmail.com>
> To: Chicago.pm chatter <chicago-talk at pm.org>
> Sent: Wed, October 20, 2010 3:29:53 PM
> Subject: Re: [Chicago-talk] logging in and out files
>
> I haven't done this myself before, but it looks like some folks have
> and have put their work on CPAN:
> http://search.cpan.org/%7Ecwest/ex-override-1.1/override.pm
>
> On Wed, Oct 20, 2010 at 9:55 AM, tiger peng <tigerpeng2001 at yahoo.com>
wrote:
>> I wrapped the open as below, and it works for the open $fh, $file but not
>> open FH, $file.
>>
>> As I need to apply the wrapping open function to lots of old script, I
>> prefer only add one line: use myLoger 'open'; into the scripts
>>
>> Is there any suggestion?
>>
>> sub open{
>> my ($package, $file, $line_number) = caller();
>> my $fullpath = Cwd::abs_path($file);
>> my $host = hostname();
>> _open_log({host=>hostname(),
>> script=>Cwd::abs_path($file),
>> file=>$_[1],
>> }
>> );
>> CORE::open(shift, shift) or die "Cannot open : $!\n";
>> }
>>
>> sub _open_log {
>> ...
>> }
>>
>>
>> ________________________________
>> From: tiger peng <tigerpeng2001 at yahoo.com>
>> To: Chicago.pm chatter <chicago-talk at pm.org>
>> Sent: Tue, October 19, 2010 11:41:10 AM
>> Subject: [Chicago-talk] logging in and out files
>>
>> Hello all,
>>
>> Does anyone have the experience on tracing input/output files used by
Perl
>> script?
>>
>> I am think if there is anyway to over write the build-in open function,
so
>> the new open function can log the file name, IO type (R, W, or RW), as
>> well
>> as the open/close timestamp. Any suggestion is highly appreciated.
>>
>> Thanks,
>> Tiger
>>
>> _______________________________________________
>> Chicago-talk mailing list
>> Chicago-talk at pm.org
>> http://mail.pm.org/mailman/listinfo/chicago-talk
>>
> _______________________________________________
> Chicago-talk mailing list
> Chicago-talk at pm.org
> http://mail.pm.org/mailman/listinfo/chicago-talk
>
> _______________________________________________
> Chicago-talk mailing list
> Chicago-talk at pm.org
> http://mail.pm.org/mailman/listinfo/chicago-talk
>
_______________________________________________
Chicago-talk mailing list
Chicago-talk at pm.org
http://mail.pm.org/mailman/listinfo/chicago-talk
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/chicago-talk/attachments/20101026/c896c63f/attachment-0001.html>
More information about the Chicago-talk
mailing list