Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

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

by fletcher_the_dog (Friar)
on Apr 19, 2004 at 18:14 UTC ( #346378=note: print w/replies, xml ) Need Help??

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

I would suggest trying your idea and seeing if it works.
sub results { return "Name:xxx Address: Main street City: Boston Phone: 123 234 2345" } $variable = &results(); print $variable;

Replies are listed 'Best First'.
Re: Re: How to collect the stdout of a subroutine call?
by Anonymous Monk on Apr 19, 2004 at 18:35 UTC
    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
      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
      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?.

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

      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....
        Ok, but it still doesn't work....

      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?

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

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2022-08-15 07:34 GMT
Find Nodes?
    Voting Booth?

    No recent polls found