Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Re: Re: How to collect the stdout of a subroutine call?

by Anonymous Monk
on Apr 19, 2004 at 18:35 UTC ( [id://346394]=note: print w/replies, xml ) Need Help??


in reply to Re: How to collect the stdout of a subroutine call?
in thread How to collect the stdout of a subroutine call?

Here is the code but it still doesn't work.
my $xx = &log; print "<b>$xx</x>";

Don't know why???
sub log { my $log_file = "log.txt"; open(LOGFILE, "$log") or die("Could not open log file."); #my %seen; my %seen = (); my %typeseen = (); # read it in my $test = "Home Company"; while(<LOGFILE>) { next unless /($test)\*(.*?)\*(.*?)\*(.*?)\*(.*?)\*(.*?)\*(.*?)\*(. +*?)$/; my ($item, $logintype) = ($1, $4); #print $item; $seen{$item}++; $typeseen{$item}{$logintype}++; } # dump it out foreach my $item (sort keys %seen) { print "$item:<br>\n"; print "\tLog in activity: ", $seen{$item}, "<br>\n"; foreach my $type (sort keys %{$typeseen{$item}}) { print "\t", $type, " activity: ", $typeseen{$item}{$type}, "<br>\n +"; } } } ####### END SUB LOG

Replies are listed 'Best First'.
Re: Re: Re: How to collect the stdout of a subroutine call?
by Roy Johnson (Monsignor) on Apr 19, 2004 at 19:15 UTC
    Your subroutine prints out information, rather than returning it. If you want to capture what is printed into a variable, you would need to have it run as a separate process (see fork) so that you can read its STDOUT. (Or, the easier way, just have it build up a string and return that, as so many others have suggested.)

    The PerlMonk tr/// Advocate
Re: Re: Re: How to collect the stdout of a subroutine call?
by jdporter (Paladin) on Apr 19, 2004 at 19:15 UTC
    If you don't want to change the code in the subroutine to accumulate and return a string, instead of printing, you can try the following. Similar but prettier techniques use non-standard modules.
    # somewhere near the top of your code, put this: { package AccumHandle; sub TIEHANDLE { my( $pkg, $s ) = shift; bless \$s, $pkg } sub PRINT { my $self = shift; $$self .= join($,,@_).$\; } } # now do this where you call the subroutine: local ACC; tie *ACC, 'AccumHandle'; select ACC; &log(); select STDOUT; my $xx = ${tied(*ACC)}; print "<b>$xx</x>";
    Btw - this question is a (currently unapproved) Categorized Question: How can I write a function's output to a scalar?.

    jdporter
    The 6th Rule of Perl Club is -- There is no Rule #6.

Re: Re: Re: How to collect the stdout of a subroutine call?
by disciple (Pilgrim) on Apr 19, 2004 at 18:48 UTC

    You must use the return statement inside your subroutine. I am not sure I understand exactly what you are trying to do from reading your code, but I am assuming you want everything you are printing to be returned (Update and not printed). In that case you need to put the data in the variable first, then return it. Like this.... (code not tested)

    my $output; foreach my $item (sort keys %seen) { $output .= "$item:<br>\n"; $output .= "\tLog in activity: ", $seen{$item}, "<br>\n"; foreach my $type (sort keys %{$typeseen{$item}}) { $output .= "\t", $type, " activity: ", $typeseen{$item}{$type}, "< +br>\n"; } return $output; }
      It is a good idea but it doesn't work....

        If you explain the problem you had with it then maybe we can provide an answer that will better suit your needs. Just saying it didn't work is not descriptive enough.

        Are there any errors? Or just unexpected results? Have you put "use strict;" and "use warnings;" at the top of your script? Not that every script must have it, but I would put it in there at least while trying to solve this problem.

      Ok, but it still doesn't work....
        Ok, but you still didn't tell us what happened...
Re: Re: Re: How to collect the stdout of a subroutine call?
by ambrus (Abbot) on Apr 19, 2004 at 20:21 UTC

    log is a builtin function (logarithm) so it is not a wise idea to define a new function with the same name. While it might not be the problem in this case, you should avoid this in the future not to fall in the trap. (I once tried to define a log function in C.)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://346394]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (5)
As of 2024-04-19 07:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found