in reply to Re: Copy a builtin sub to a different name and then override
in thread Copy a builtin sub to a different name and then override

still the same problem with this:

#!/usr/bin/env perl use strict; use warnings; my $total_sleep_time = 0; BEGIN { my $actual_sleep = \&CORE::GLOBAL::sleep; *CORE::GLOBAL::sleep = sub { $total_sleep_time+=$_[0]; $actual_sleep-> +($_[0]) } } # use this module and the other # ... sleep(2); print "total sleep is $total_sleep_time\n";
thanks

Replies are listed 'Best First'.
Re^3: Copy a builtin sub to a different name and then override (robust)
by LanX (Saint) on Jun 02, 2018 at 18:34 UTC
    > still the same problem with this:

    > ...

    > my $actual_sleep = \&CORE::GLOBAL::sleep;

    This should solve it in a robust manner:

    my $actual_sleep = exists &CORE::GLOBAL::sleep # already overridden + ? ? \&CORE::GLOBAL::sleep : \&CORE::sleep

    Point is you are changing sleep globally, but some other modules might be trying to do the same thing already. (well ...)

    If you install your override later, you'll be playing safe.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

    update

    even more robust with defined instead of exists , see Haarg's comment in this thread for details.

Re^3: Copy a builtin sub to a different name and then override
by LanX (Saint) on Jun 01, 2018 at 23:30 UTC
    > still the same problem with this:

    Really?

    You still have Deep recursion on anonymous subroutine ?

    As I said that's the normal way to install a wrapper, but in the case of builtins it seems risky.

    calling CORE::sleep() should be the recommended way.

    ... but I seem to remember reading that overriding sleep used to be problematic.(?)

    I'll look tomorrow into it.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      No that's fine, your later suggestion CORE::sleep() worked great! thanks

        and here is the reason why, at least with 5.16
        warn $]; warn \&CORE::GLOBAL::sleep; warn \&CORE::sleep; &CORE::GLOBAL::sleep(3);
        5.016003 at d:/Users/lanx/pm/core_sleep.pl line 1. CODE(0x328420) at d:/Users/lanx/pm/core_sleep.pl line 4. CODE(0x349718) at d:/Users/lanx/pm/core_sleep.pl line 5. <-- differen +t! Undefined subroutine &CORE::GLOBAL::sleep called at d:/Users/lanx/pm/c +ore_sleep.pl line 7.

        You are trying to build a wrapper around an non-existent function.

        You haven't told us which version you use, but I doubt that CORE::GLOBAL:: is populated by default.

        What you originally tried, something like:

        *old = *CORE::GLOBAL::sleep

        is aliasing the two symbols (two symbols pointing to the same typeglob)

        But after populating the code slot with *CORE::GLOBAL::sleep = sub{} both will point to the same sub.

        *old = *CORE::GLOBAL::sleep; *CORE::GLOBAL::sleep = sub { warn " **** beware of morons **** "}; &old(); # oops warn \&CORE::GLOBAL::sleep; warn \&old;
        **** beware of morons **** at d:/Users/lanx/pm/core_sleep.pl line 2. CODE(0x4c9478) at d:/Users/lanx/pm/core_sleep.pl line 7. CODE(0x4c9478) at d:/Users/lanx/pm/core_sleep.pl line 8. <-- identical +!

        That's why you get a circular call!

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

        update

        same with 5.18 on linux

        lanx@ubuntu14-large:~$ perl warn $]; warn \&CORE::GLOBAL::sleep; warn \&CORE::sleep; &CORE::GLOBAL::sleep(3); __END__ 5.018002 at - line 1. CODE(0x1804cb8) at - line 2. CODE(0x1830398) at - line 3. Undefined subroutine &CORE::GLOBAL::sleep called at - line 4.

        lanx@ubuntu14-large:~$ perl *old = *CORE::GLOBAL::sleep; *CORE::GLOBAL::sleep = sub { warn " **** beware of morons **** "}; &old(); # oops warn \&CORE::GLOBAL::sleep; warn \&old; __END__ **** beware of morons **** at - line 2. CODE(0x2089448) at - line 5. CODE(0x2089448) at - line 6.
        A reply falls below the community's threshold of quality. You may see it by logging in.