in reply to Overriding caller everywhere

Your test code that calls caller() has already been compiled before you override anything. Doing the overriding in a BEGIN block is one way to fix that.

- tye        

  • Comment on Re: Overriding caller everywhere (BEGIN)

Replies are listed 'Best First'.
Re^2: Overriding caller everywhere (BEGIN)
by xdg (Monsignor) on Aug 06, 2007 at 22:48 UTC
    Doing the overriding in a BEGIN block is one way to fix that.

    And, to be clear for the OP, when you use a module like Sub::Uplevel or Hook::LexWrap (or Contextual::Return), the compilation of those modules happens immediately as a BEGIN block (c.f. docs for use), thus caller is replaced globally before the rest of your code compiles.

    use Sub::Uplevel; # *CORE::GLOBAL::caller replaced here print caller(); # calls the replacement

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re^2: Overriding caller everywhere (BEGIN)
by Sartak (Hermit) on Aug 07, 2007 at 00:45 UTC
    Doing it in a BEGIN block does seem to work in this example. But why does the identical glob test work without BEGIN? :)

      Overriding of glob is special-cased. Instead of changing things so that Perl code is compiled to call your replacement routine "directly", the built-in &CORE::glob is still called and it notices (at run-time) the override and calls your replacement routine (and passes an extra argument that provides the context so that your replacement can correctly handle repeated calls made in scalar context). So you can't use CORE::glob("foo") to bypass this override (and you can't change the prototype of glob like you can with other overridden built-ins when using a recent version of Perl).

      - tye