in reply to PDL and srand puzzle

Interesting replies - including aspects that I had not even considered.

I think that one lesson (for me, at least) is that I should not have expected "-MPDL" to be as innocuous as I had assumed.
For that level of innocuity, I think I should instead have used "-mPDL".

But I'm still a bit confused about perl's handling of "some_func" when both "main::some_func" and "CORE::some_func" exist.
In the one-liner I gave (that loads PDL), both "main::srand" and "CORE::srand" exist - and perl decides that "srand(3)" means "main::srand(3)".
But in this next one-liner (where both "main::sqrt" and "CORE::sqrt" exist) perl goes the other way - and decides that "sqrt(2)" means "CORE::sqrt(2)".
D:\>perl -wle "print sqrt(2);print main::sqrt(2); print CORE::sqrt(2); +sub sqrt { return sprintf('%.6g', $_[0] ** 0.5) }" 1.4142135623731 1.41421 1.4142135623731
Why the inconsistency ?
And why no warnings about the ambiguity of calling "some_func()" when both "main::some_func()" and "CORE::some_func()" exist ?

Cheers,
Rob

Replies are listed 'Best First'.
Re^2: PDL and srand puzzle
by sectokia (Friar) on Jun 05, 2024 at 05:50 UTC

    The CORE namespace take priority. This is important because otherwise you would end up in situations like you have with PDL's srand all the time. If you want to override the core function you can do it like this:

    perl -wle "use subs 'sqrt'; print sqrt(2); print CORE::sqrt(2); sub sq +rt { return sprintf('%.6g',$_[0] ** 0.5) } " 1.41421 1.4142135623731
      The CORE namespace take priority.

      Thanks for that - I now think I know what the rule is:
      <RULE>
      If main::foo and CORE::foo both exist, then "foo" calls main::foo if main::foo has been imported in from some module.
      Otherwise "foo" calls CORE::foo.
      </RULE>
      Is that the way it works ?

      I'm still a bit puzzled as to why there should be this difference - but if that's the rule, then that's the rule.

      Cheers,
      Rob

        If you declare a sub foo() in your perl code, and core::foo already exists, you will get a warning "Ambiguous call resolved as CORE::foo(), qualify as such or use &" and core::foo will be called.

Re^2: PDL and srand puzzle
by haj (Vicar) on Jun 05, 2024 at 06:59 UTC

    I guess that the call to sqrt gets compiled to CORE::sqrt before the interpreter processes your subroutine declaration. You can get the warning about the ambiguity if you declare your subroutine before calling sqrt (I got rid of the percent format because it breaks shell syntax on Linux):

    perl -wle "sub sqrt { return q(more than 1.4) } print sqrt(2);print ma +in::sqrt(2); print CORE::sqrt(2);"
    That prints:
    Ambiguous call resolved as CORE::sqrt(), qualify as such or use & at - +e line 1. 1.4142135623731 more than 1.4 1.4142135623731
      Ambiguous call resolved as CORE::sqrt(), qualify as such or use & at -e line 1.

      Thanks. I had tried pre-declaring the sub but I must have stuffed up that test because I certainly didn't see that warning.
      I've just double-checked, and the warning is present for me, too.

      Update: Oh ... and for the warning to appear, the ambiguity has to be detected at compile time.

      Cheers,
      Rob.