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

Re: Constant redefined

by davido (Cardinal)
on May 31, 2005 at 04:30 UTC ( [id://461920]=note: print w/replies, xml ) Need Help??


in reply to Constant redefined

The answer to this question is found in constant (the documentation for the constant pragma), where it states:

In the current implementation, scalar constants are actually inlinable subroutines. As of version 5.004 of Perl, the appropriate scalar constant is inserted directly in place of some subroutine calls, thereby saving the overhead of a subroutine call. See "Constant Functions" in perlsub for details about how and when this happens.

That statement means that constants are both declared at, and solidified at compiletime, and cannot be altered. You would literally have to go back and alter all the inlined values in the compiled code at runtime. Constants are...constant. ;)

The fact that constants are translated into inline values instead of the subroutine calls that they "look" like means that even if you tried to assign a new subroutine to the typeglob by which the constant is named, you can't. The typeglob for the sub seems to be forever tied to that inlined value.

Of course if you read on in the docs to the BUGS section you'll find the following:

In the current version of Perl, list constants are not inlined and some symbols may be redefined without generating a warning.

Exploiting that bug should not be for the faint of heart. In fact, exploiting it should just not ever be done, because its possible the behavior will go away if someone decides to fix that bug.


Dave

Replies are listed 'Best First'.
Re^2: Constant redefined
by paulski (Beadle) on May 31, 2005 at 04:43 UTC
    I'm aware of how constants work i.e. I did read the doco before I asked :-) and realise that PERL constants are just inline subs. I'm more interested in suppressing the error message, if possible.

    Thanks,

    Paul

      I'm sorry for misunderstanding the intent of your question. Ok, so despite the fact that it violates the intent of constants, you're looking for a way to suppress any error message anytime a constant is defined again with the "use constant..." directive. Here's some rope:

      use warnings; use strict; BEGIN{ open OLDERR, '>&', \*STDERR or die "Couldn't save STDERR\n$!"; close STDERR; } INIT{ open STDERR, '>&', \*OLDERR or die "Couldn't retrieve STDERR\n$!"; } use constant PI => 3.14; use constant PI => 1000; print PI, "\n";

      You are now suppressing any error messages that would occur during the stage of compilation where 'use' directives are being sorted out and compiled. That means there are a lot of other errors you won't see. In fact, I doubt you would even see any error caught by my 'or die...' clauses while saving away STDERR. I did give STDERR back to you for runtime stuff though. But this whole thing seems like a BAD IDEA.

      By the way, holli is wrong about being able to wrap it in an eval BLOCK. I tried that too. ;)


      Dave

      You can suppress this error as you can suppress every error. Put in an eval BLOCK. But then the constant will still have the old value.

      Oh yeah. Compile time. My bad.


      holli, /regexed monk/

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (2)
As of 2025-03-17 04:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    When you first encountered Perl, which feature amazed you the most?










    Results (54 votes). Check out past polls.