[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