Wiggins has asked for the wisdom of the Perl Monks concerning the following question:

An integration problem. I have code for filling in forms and mailing them. I wrote a TK GUI to allow viewing the files before the merge and such. Now I wrapped the mailing code into a package and 'use' it. But I want both the TK GUI and the Mail Merge to use one log file, that I open in the TK mainline code.

?? How do I pass/assign an already open file handle into my package variable so the package can log into my existing log file?
A minimized test program...
package test_a; # optionaly; to be set/over-ridden from user code.... $AuxDataFile= "AuxData"; $TmpltFile= "LinuxScript-Text.txt"; $DataCSV = "LinuxScript-TEST-Data.csv"; $AttachmentFile; *LogFile; #################### Subs ########################### sub SetLog ( $ ){ *LogFile = @_; #Adv Perl Programming (Rel 1) pg 49 } sub TestLog { printf LogFile "a::TestLog print\n"; } 1;
Now the mainline calling code:
use test_a; open LOGF, ">log.txt"; $|=1; #*test_a::LogFile =*LOGF ; test_a::SetLog (*LOGF) ; printf LOGF "Run started\n"; test_a::TestLog(); printf LOGF "Run ended\n";
The printf line from the test_a package never gets into the log file????
What am I missing?

Replies are listed 'Best First'.
Re: sharing filehandles
by holli (Abbot) on Jun 29, 2008 at 16:13 UTC
    I'd suggest using Log::Log4perl which has already solved that and other problems for you =)


    holli, /regexed monk/
Re: sharing filehandles
by pc88mxer (Vicar) on Jun 29, 2008 at 16:21 UTC
    Try this for SetLog:
    sub SetLog { my $glob = shift; *LogFile = *$glob; }
    Update: *LogFile = *{shift()} also works.

    In general, though, I would avoid using barewords as file handles in this case and use scalars instead. "Advanced Perl" came out over 10 years ago, and a lot of practices have changed since then. (Update: I suppose you could have the 2005 edition, but still...) To pass file handles around it's just better to use scalar refs:

    package test_a; my $LOGFH; sub SetLog { $LOGFH = shift; } sub TestLog { print $LOGFH "test_a::TestLog...\n"; } package main; ... test_a::SetLog(\*LOGF);
      Ref: "I suppose you could have the 2005 edition, but still..."

      I do have the "2nd edition", which, during a quick scan, I find to be a complete mis-naming. It should be "Volume 2". Since the author is different; and there appears to be little overlap in the subject matter.So, it is volume 2, focusing on topic in vogue 10 years later.

      I will be looking into the suggested solutions. I failed to mention that the eventual run-time environment is MS XP, using ActiveState. That means I prefer any solution that does not depend upon packages that may not be available in both environments.
      And thanks to all the quick responses!!
Re: sharing filehandles
by apl (Monsignor) on Jun 29, 2008 at 18:46 UTC
    CPAN has a number of packages that could help you. Log::Info is one such.
Re: sharing filehandles
by zentara (Cardinal) on Jun 30, 2008 at 14:45 UTC
    In case you still are looking, you may need to pass the fileno of the filehandle to share it. Like in threads, the filehandles can be shared between theads thru the fileno. So as long as all code share the same process something like this should work.
    #UNTESTED # in one place open(LOG, " >/foo/logfile") or warn "$!\n"; my $fileno = fileno(LOG); # then pass the fileno somehow to the other package, # thru an option or our variable open (my $fh, ">&=$fileno") or warn "$!\n";

    I'm not really a human, but I play one on earth CandyGram for Mongo