Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Overriding CORE::GLOBAL::warn/die

by clueless newbie (Chaplain)
on Sep 21, 2012 at 17:30 UTC ( #994954=perlquestion: print w/replies, xml ) Need Help??
clueless newbie has asked for the wisdom of the Perl Monks concerning the following question:

Suppose is

# package CORE::GLOBAL; use strict; use warnings; use subs 'warn'; sub warn { print "WARN '@_'!\n"; CORE::warn @_; }; # die: 1;

and is

# #!/usr/bin/perl use strict; use warnings; warn 'first warn'; use warn; warn "second warn";

Then executing produces

first warn at line 6. WARN 'second warn'! second warn at line 9.

Why doesn't the first warn (the warn prior to the "use warn;") utilize the CORE::GLOBAL::warn? Why in this case does the location of the "use warn;" matter?

Replies are listed 'Best First'.
Re: Overriding CORE::GLOBAL::warn/die
by chromatic (Archbishop) on Sep 21, 2012 at 18:35 UTC

    By the time Perl compiles the use warn; statement, it's already decided that the first warn refers to the builtin warn. Perl won't go back and recompile code it's already compiled when you override a keyword (that's not possible in some cases).

      Thank you! I thought it was something along those lines.

Re: Overriding CORE::GLOBAL::warn/die
by Anonymous Monk on Sep 21, 2012 at 21:55 UTC
Re: Overriding CORE::GLOBAL::warn/die
by greengaroo (Hermit) on Sep 21, 2012 at 18:19 UTC

    Try this:

    my $ref = { 'key' => 'value' }; print Dumper $ref; use Data::Dumper; print Dumper $ref;

    Basically, the first "print Dumper" fails and the second works fine.

    My guess is you are confused by this statement in the documentation for use: Because use takes effect at compile time, it doesn't respect the ordinary flow control of the code being compiled. In particular, putting a use inside the false branch of a conditional doesn't prevent it from being processed.

    The way I understand it is even if the "use" statements are processed at compile time, it doesn't mean the module functions become omnipresent. It will respect the order in which the statements are written: from top to bottom.

    In your case, the "use warn" is processed at compile time but when you do your first warn statement, the module's "warn" function is not available yet.

    Now, my question to you is, why does it mater? Is there something specific that you are trying to achieve and for that you need to "use" your module somewhere else, after you actually use its functions?

    Please enlighten us!

    There are no stupid questions, but there are a lot of inquisitive idiots.

      I'm merely attempting to debug some code that makes use of a CORE::GLOBAL::die to "rat out" the offending code. It sometimes fails and I wished to know why.

        We may be of more help if you post the code you are trying to debug. Please expose your problem, we'll give it a try.

        There are no stupid questions, but there are a lot of inquisitive idiots.
Re: Overriding CORE::GLOBAL::warn/die
by sundialsvc4 (Abbot) on Sep 21, 2012 at 18:42 UTC

    I would not advise overriding any “core” functionality, because of course that would be all-encompassing.

    Consider using code such as Exception::Class, which leverages the fact that you can in fact “die” with an object, not merely a text string.

    I simply think that it is very inadvisable to make any changes that have “global” ramifications to suit a “app-specific” requirement ... because they expose the entire software (every CPAN module, etc.) to the very considerable side-effects of your change.   If I may opine, “Abandon All Hope, Ye Who Enter Here.”   I’m scrambling away from the very thought of this situation so fast, I don’t even care why it’s not working ...  My spider-sense is going off; my trusty elven sword is glowing bright blue ...

      Iím scrambling away from the very thought of this situation so fast, I donít even care why itís not working ... My spider-sense is going off; my trusty elven sword is glowing bright blue ...

      Your senses do not deceive you! Involved is a tie of STDERR, BEGIN/INIT/END blocks, implicit source filtering (of modules used) by means of unshifting a sub onto @INC, the override of core die ... and I can't remember what else. And most of the time it does its job quite nicely. And when it doesn't ... I remove the use statement and debug the normal way.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://994954]
Front-paged by Arunbear
[ovedpo15]: how fast and a good way to print error if more than one out of three variables are defined? for example if there are $a $b $c. I want that if for example $a and $b are defined - print error (also for $a and $c or $b and $c)
[ovedpo15]: its easy with three "if"s or one long "if" but is there a "nice" way :)

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (6)
As of 2018-04-22 13:12 GMT
Find Nodes?
    Voting Booth?