Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

print statements in perl pakages seem to be masked from STDOUT

by holandes777 (Scribe)
on Mar 07, 2018 at 16:06 UTC ( [id://1210456]=perlquestion: print w/replies, xml ) Need Help??

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

I am having to deal with SES (Someone Else's Sh(tuff)) so I am a bit out of synch. Forgive me if this is a "DOH!" question.

I am dealing with a Perl program that calls a package. The main code is extremely stringy and the package seems contructed well. I started putting print statements in the methods of the package and they were printing on STDOUT (my console). Suddenly they stopped. I tried creating a filehanle and used print to the filehandle a-la: print {$self->{fileout}} "what I want to print\n"; Which also does not seem to work (It is not $!, the output should be voluminous).

I must be missing a basic concept about the interaction between an imported module and STDOUT. So my question is: If I want to have a package print to STDOUT, is there something "special" that needs to be done?

  • Comment on print statements in perl pakages seem to be masked from STDOUT

Replies are listed 'Best First'.
Re: print statements in perl pakages seem to be masked from STDOUT
by Corion (Patriarch) on Mar 07, 2018 at 16:13 UTC

    It's hard to tell without seeing relevant code, but if the code was short enough likely you would have found the culprit already.

    The intervening code might close STDOUT or use select to select a different filehandle:

    sub nasty1 { close STDOUT; } nasty1(); print "everybody keep silent"; # maybe you get a warning that STDOUT w +as closed
    sub nasty2 { open my $fh, '>', 'output.txt' or die $!; select $fh; # everybody keep silent print "everybody keep silent"; # this shows up in } nasty2(); print "everybody keep silent"; # this shows up in the output file

    Maybe you did not properly create and open your debug filehandle.

    Maybe the code that should print stuff never even gets called at all.

      Looks like you're pointing me in the right direction. so I will pose a question: I am just dropping print statements in the package (the module).

      # In the main .pl use ThisPackage; ... my $the_package = ThisPackage->new(); ... (this other guys code) print "What is the value of var_here? $var_here\n"; # my debug statem +ent gets printed as What is the value of var_here? CornFlakes (more of this other guys code) # In the package: package ThisPackage; ... sub new{ my ($class, $self)=@_; ... } (this other guys code) print "What is the value of var_in_package? $var_in_package\n"; # my +debug statement does NOT get printed out as the statement in the main + program did. (more of this other guys code)

      should I expect it to print is STDOUT? The print statements I put in the .pl file are printed to STDOUT but anything inside the package does not get printed

        Maybe. Where is that print exactly? Inside a function? If so, are you sure it is called? Maybe you can try warn instead of print, or even die, they print to STDERR rather than STDOUT so you should be able to see them in the console (and since die also stops the execution, if you use it and nothing changes, you're probably modifying code that actually never gets called). If you do see something with warn, you can search for select in the code, which will change the default output for print. But since you didn't manage to write to a file with an explicit filehandle for print, it's also probable that you are modifying code that isn't run.

        In a module, supporting code (not in subroutines) should get run when you use the module, so I would have expected the "What is the value of var_in_package" to print when you ran use ThisPackage;. For example:

        #./ThisPackage.pm package ThisPackage; sub new { local $, = ", "; local $\ = "\n"; print __PACKAGE__."::new(@_)"; } print "Dummy code gets run at compile/use time\n"; 1;
        #./pkg.pl BEGIN { print "this should print before\n" } use lib '.'; use ThisPackage; ThisPackage::new(qw/hello world/); BEGIN { print "this should print after the use, but before the new\n" +}
        # output this should print before Dummy code gets run at compile/use time this should print after the use, but before the new ThisPackage::new(hello world)

        Does my code do the same for you? If so, maybe it will help you figure out what's wrong with your code.

        specifically, if you want to print values inside the package's functions, you have to include the prints inside. If you put prints outside the functions in the package, they will only execute the once, and none of the package's functions will have been run yet, so probably won't have changed package variables (assume that's what you're expecting)

Re: print statements in perl pakages seem to be masked from STDOUT
by AnomalousMonk (Archbishop) on Mar 07, 2018 at 18:06 UTC
    I started putting print statements in the methods of the package and they were printing on STDOUT ... Suddenly they stopped.

    So either the way modules work suddenly changed, or else something in your code and/or system did. I just want to reinforce the idea, already expressed directly or indirectly by other monks, that the latter possibility is by far the most likely.

    Are you even working on the code you think you're working on? Have you inadvertently started working on a different set of similar or identical files? I remember a jolly hour or two I once spent debugging some C/C++ code. I happily tried one fix after another; none had any effect. I finally noticed that one of the changes I had made was not syntactically correct, but had compiled anyway. I tried inserting the magical  snifiasdha; statement and compiling again. The compiler was still happy. The penny finally dropped. It turned out that another programmer had placed a huge block of code into a

    #if 0 ... ... #endif
    "block comment" that my syntax highlighter could not detect, and I had been "debugging" dead code. Massive facepalm. Thus do we live and learn.


    Give a man a fish:  <%-{-{-{-<

Re: print statements in perl pakages seem to be masked from STDOUT
by Marshall (Canon) on Mar 07, 2018 at 17:53 UTC
    I started putting print statements in the methods of the package and they were printing on STDOUT (my console). Suddenly they stopped.
    This is indeed odd. What did you change between "it works" and "it doesn't work"? STDOUT and STDERR are available everywhere unless the program specifically closes them or re-opens them to somewhere else - IMO both typically bad ideas - I'm sure there is some kind of exception, but I'd think long and hard before doing either. This is such an odd thing to do that I'd be surprised if that is what you have. However, anything is theoretically possible!

    I don't think this is an issue here, but it might be. You should be aware of one fine point. STDOUT is by default buffered. STDERR is by default un-buffered. You can unbuffer STDOUT by adding the line: $|=1; to the top of main and each package. When you do that, any print to STDOUT will appear on the console immediately. The default behavior is to wait until some number of lines are ready for print and then they all appear at once. When the program exits normally, all buffers are flushed. However, I don't think that happens if you CTL-C or kill the process (not a normal program directed exit). If your program is hanging and you CTL-C it, you might not see previous STDOUT prints. Unbuffer STDOUT for debug. This slows down the max print rate, but has the advantage that Error messages (STDERR) and prints to STDOUT will appear in the correct time ordered sequence. Otherwise you might see an warning message and then 4-5 lines later see a STDOUT line that was actually related to the error message.

    I must be missing a basic concept about the interaction between an imported module and STDOUT. So my question is: If I want to have a package print to STDOUT, is there something "special" that needs to be done?
    Typically, the answer is "No".
Re: print statements in perl pakages seem to be masked from STDOUT
by 1nickt (Canon) on Mar 07, 2018 at 16:27 UTC

    The main code is extremely stringy

    What does that mean? I'm not familiar with "stringy" to describe code.

    Suddenly they stopped.

    What did you do before it suddenly stopped printing your debug statements? What was the effect of undoing the most recent thing you did?


    The way forward always starts with a minimal test.

      I wish I could tell you what happened. I added print statements in the package, I was seeing them in the output, I added a print statement, I stopped seeing any output from the package, I removed the recently addded print statement, I could no longer see any output from the package

      Years ago I remembered that I tried to print in a package and it did not work, I wrote it off to scope and moved on with debug objects. My question is: should I expect a print statement to provide output on STDOUT as it does when the print statement is in the main body of the .pl?

      If the answer is "no". can you point me at something that will help me output data from the package so I can see what is happening inside that code?

        My question is: should I expect a print statement to provide output on STDOUT as it does when the print statement is in the main body of the .pl?

        You should definitely see the print statements on STDOUT from a module, just like the script, unless the module is hijacking STDOUT somehow per Corion's post above.

        The answer is a conditional "yes" as described by Corion and stevieb. If you are suspicious that STDOUT has been overridden, you could always open your own filehandle and print your debug statements to a file. But if

        print {$self->{fileout}} "what I want to print\n";
        does not work, then you may not have opened your filehandle successfully, or it may not be stored in the variable you think it is. Did you check?


        The way forward always starts with a minimal test.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1210456]
Approved by stevieb
Front-paged by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (6)
As of 2024-04-18 17:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found