Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??

Hello there monks,

I feel like this is something that should be picked to pieces somewhere but my best searching efforts haven't turned up an answer for my case. So I'll provide a unexpectedly long example and hopefully some wise monk can nail this down:

I have (as usual) an admittedly clunky script that use feature 'say' for basic debug outputs. What can I say, I was writing this pretty hastily and didn't think this script would evolve to the point where I would need to consider verbosity. All those annoying say messages are certainly unnecessary to the users but I'd like to keep them in the code just for later debugging.

Yeah, hold on, I know you probably have all kinds of simple fixes - let's nix those right now and move on to the actual problem at hand.

I could write a cute one-liner that goes and comments out all the say statements - then I could toggle as needed from CLI. Nope! Unfortunately some of them were unwisely inserted in compound and|or statements or are just otherwise hard to identify and exclusively comment. It doesn't help that my unhealthily compulsive use of PerlTidy leads to multi-line statements based on a line length limit, so no dice.

I could create a verbosity variable and use that to turn each individual say statement on or off:say 'this is a feature' unless $verbose; No, thank you! I hate having to write that into each statement or even doing regex sub to make it happen. That's just entirely too much repetition.

I'm down to a couple options. First option being that I roll my own say sub:

sub say {print shift, "\n" if $verbose}

It's easy, sure. But that's not the point! I want to be able to disable or redefine an imported subroutine. Secondly, I could replace all the says to warn. Not going to happen either, I use warnings already because they are error messages for users of this script not just status updates and boring information dumps. Retrospect tells me that maybe warnings are better suited for debug output and STDOUT print routines for user output since toggling warnings on and off is simple enough but it is what it is.

Okay, so enter no which should presumably be able to unimport a target routine from any module that supports it. Deleting it right out of definition in the current package scope. Think I've got that right.

Unfortunately I can't have say something like no feature 'say' unless $verbose;, can't use or no in conditional or anything like that. Probably something to do with that you can't have code blocks (like BEGIN) get conditionally executed due to Perl's interpreter flow, correct me if I'm wrong. But I guess I can try this:

use feature 'say'; unless ($verbose) { no feature 'say'; #say 'this goes unsayable'; } say 'said';

No dice on that, no only applies to the current code block {}. I was expecting it to operate over the package's scope. So it operates kind of like local does.

Let's try something new; how about manually deleting/redefining the subroutine in the symbol table?

use feature 'say'; undef &say; *say = \&not_say; say 'test'; sub not_say { print 'not saying'; }

Maybe I'm getting my namespaces all mixed up because that doesn't seem to redefine the sub at all.

I'm done fooling around - it's CPAN time. The most likely candidate appears to be Sub::Delete, which promises to delete a subroutine (cleanly, I don't yet understand enough of Perl's mechanics to fully understand what it means by that).

use feature 'say'; use Sub::Delete; delete_sub 'say'; say 'testing';

Doesn't do the trick either. I also went back for the past couple examples and tried specifying the sub as 'main::say' and 'feature::say' but got no love there, either.

So my silly example aside, I'm missing a piece of this puzzle. I thought that subs got imported into the current package's scope, which means that I can remove or redefine them. Where is this sub hiding?

TLDR:
How do I dynamically redefine imported subroutines?


In reply to Redefining Imported Subs: of scope and no by temporal

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others making s'mores by the fire in the courtyard of the Monastery: (8)
    As of 2014-11-25 23:38 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      My preferred Perl binaries come from:














      Results (160 votes), past polls