Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you want to keep everything in the same file, why not put the logger at the top in a file scoped lexical.</p> <pre><code>GetOptions( do_logging =&gt; \$do_logging ); my $logerr = $do_logging ? sub {logging_code_here()} : sub {}; </code></pre> <p><code>$logerr</code> is now available in any package defined after that point in the same file.</p> <p>However, it is generally faster to structure your logging calls as follows:</p> <pre><code>my $logerr = sub { logging_code_here() }; $logerr-&gt;("some string $some_var") if $do_logging; </code></pre> <p>that way you avoid a subroutine call and the string argument to $logerr does not need to be calculated if logging is off.</p> <p>You can also setup logging levels:</p> <pre><code>$logerr-&gt;("starting loop") if $do_logging; for (@big_array) { $logerr-&gt;("processing $_") if $do_logging &gt; 1; ... } </code></pre> <p>EDIT: While I don't think its the best practice, based on your comments, here is what you are probably looking for (a pragma):</p> <pre><code>use 5.010; use warnings; use strict; BEGIN { # compile time $INC{'log.pm'}++; # block 'require log;' package log; sub is_active {(caller 1)[10]{log}} # test the hints hash sub import { $^H{log} = 1; # set the hints hash for 'log' my $logmsg = (caller).'::logmsg'; # name of caller's sub no strict 'refs'; *$logmsg = sub {print "logging: @_\n" if is_active} # install sub unless *{$logmsg}{CODE}; # unless we did already } sub unimport { $^H{log} = 0; # unset the hints hash } } package MyPkg; use log; logmsg 'hello, world!'; { no log; logmsg 'nope, not here'; } logmsg 'back again'; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. CO@Eric Strom: But then wouldn't I need to reference package main to pull them into my object packages? As in `main::$logerr->("processing $_") if $do_logging > 1;`. The whole point is I'm trying to be concise and reduce the amount of typing and clutter in the code. For different logging / debug levels I simply have different functions, i.e. `loginfo1`, `loginfo2`, etc.. I would think that Perl is smart enough to optimize away a call to an empty function when logging is turned off. Thanks, but I don't think your solution meets my requirements.
      singulars
    2. CO@Robert S. Barnes => No, that is not the way `my` variables are scoped. Lexicals are not members of a package, but of a scope level, so if a lexical variable is defined at the root scope of a file, it will be visible in every package/block below it in the same file. Additionally, I don't think perl will optimize away the sub call, and calculating the message text before the sub call can be slow (for example if the logging code is in a tight inner loop). by moving the check outside the sub and into the calling code, you could prevent a great deal of unnecessary computation at debug level 0.
      singulars
    3. CO@Eric Strom: Thanks for the clarification on visibility. However, when I tried putting the log function at global scope in main it wasn't visible in the packages below it. Are you saying a `my` variable would be visible while one without the my declaration wouldn't? Regarding performance of one vs. the other the only real way to know is testing it.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload