http://qs321.pair.com?node_id=720674

blazar has asked for the wisdom of the Perl Monks concerning the following question:

To put it as short as possible, this popped out in clpmisc while trying to help someone to override -e (which appears not to be possible) and I'm pasting hereafter the relevavant part of what I wrote there:


Actually, now that I think of it, I don't know if -X functions are overridable, and you made me discover something interesting: people generally check the prototype of CORE:: functions because if they are not ovverridable then it returns undef - but then please note that the inverse implication does not hold. (E.g. require returns undef() but I have seen it duly overridden.) Now, I tried to see what happens with -e() and it turns out that it gives a run-time error I had never seen:

whisky:~ [09:58:08]$ perl -E 'say prototype "CORE::$_" // "undef" > for qw/rand require -e/' ;$ undef Can't find an opnumber for "-e" at -e line 2.

Now, I don't even know if this is a proper SoPW since I understand that, to put it simply, "something strange happens with these strangely named functions, even if the docs say that they apart that detail they're not different from any other unary operator..." But I would like to know more about this error, anyway: was it to be expected, or can I check the prototype of those functions in some other way?

--
If you can't understand the incipit, then please check the IPB Campaign.

Replies are listed 'Best First'.
Re: Previously unseen error in connection with -X functions
by almut (Canon) on Oct 31, 2008 at 11:32 UTC
    if they are not overridable then it returns undef - but then please note that the inverse implication does not hold.

    yes, those with an undefined prototype are still overridable, but you can't make the replacement function behave like the original one in every way (due to parsing issues), for example exec/system's indirect object syntax.

    BTW, I was once also in desperate need to override the filetest operators... so I'm pretty sure it cannot be achieved with the current implementation — but also see the patch mentioned in footnote 2 in the post I linked to.

      BTW, I was once also in desperate need to override the filetest operators... so I'm pretty sure it cannot be achieved with the current implementation — but also see the patch mentioned in footnote 2 in the post I linked to.

      I personally believe that in that case one may use source filters as an extreme resource, but... they're generally deprecated and I presume even more so in the context of tests, which is most probably the one in which need of overriding and mocking functions is arising... (Was it yours too?)

      --
      If you can't understand the incipit, then please check the IPB Campaign.
        ... (Was it yours too?)

        My need to override didn't arise in the context of testing, but with trying to write a 'compatibility module', which would allow to run ancient jperl v5.005 code in a recent version of Perl without modifications (large existing, tested codebase). Specifically, the problem was with trying to transparently convert japanese filenames between legacy and unicode encodings, because 5.005 did not support unicode, while modern versions of Perl cannot easily be configured to operate in the same old way that worked with jperl.

        Writing a source filter would have meant being able to reliably identify filename related code fragments in arbitrary Perl code... which I anticipated to be way too complex to get working in the time frame alotted to the project.  (For anyone interested, I eventually decided to take the easiest route of utilising the deprecated USING_WIDE win32-perl macro (no longer available in Perl 5.10), which works reasonably well — In other words, I'm hoping there won't be significant code rot in Perl 5.8.8 before I retire... ;)

Re: Previously unseen error in connection with -X functions
by JavaFan (Canon) on Oct 31, 2008 at 11:25 UTC
    Now, I don't even know if this is a proper SoPW since I understand that, to put it simply, "something strange happens with these strangely named functions, even if the docs say that they apart that detail they're not different from any other unary operator..."
    Since you cannot override operators (although you can overload certain operations - but said overload magic hangs off the operand, not the operator itself), it isn't surprising you cannot override -e. Note also that the error message you get you also get if you replace '-e' with '+', 'cmp', 'feeble' or any other non-function.

    Here's another way to see -e isn't a function:

    perl -wce '&-e' Bareword found where operator expected at -e line 1, near "&-e" (Missing operator before e?) syntax error at -e line 1, next token ??? -e had compilation errors.
    It wouldn't be a syntax error if -e was a function.

    Note also that perlfunc says they are operators:

           -X FILEHANDLE
           -X EXPR
           -X DIRHANDLE
           -X      A file test, where X is one of the letters listed below.  This
                   unary operator takes one argument, either a filename, a
                   filehandle, or a dirhandle, and tests the associated file to
                   see if something is true about it.
    
      Here's another way to see -e isn't a function:

      I personally believe that it's too bad it isn't. Actually, it even seems one, not to mention that its documentation is available under perldoc -f -X! Of course Perl 6 knows better by making all operators actual functions. But I wouldn't dare asking that much in 5's realms: perhaps one difficulty in this sense is the new stacking facility à la -f -w -x $file however AIUI from the docs that's just syntax fancy. Which I read in the sense that the parser takes care of it making it into the equivalent of -x $file && -w _ && -f _, but at this point ideally those tests may be overridden and without interfering at all with the additional magic, which would be completely orthogonal.

      --
      If you can't understand the incipit, then please check the IPB Campaign.
        I think one of the reasons -f isn't a function is that it violates the naming rules. Identifier names have to start with letters, and dashes are not allowed. -f violates that. Changing it would probably mean changing the lexer. Which I don't think many people are willing to do.

        perhaps one difficulty in this sense is the new stacking facility à la -f -w -x $file however AIUI from the docs that's just syntax fancy. Which I read in the sense that the parser takes care of it making it into the equivalent of -x $file && -w _ && -f _,
        I was under the impression that the stackability was archieved by -f and friends returning magical values. But if there's magic, if doesn't show with Devel::Peek::Dump, so I'm probably wrong in my impression.
Re: Previously unseen error in connection with -X functions
by Anonymous Monk on Oct 31, 2008 at 11:34 UTC

      I personally believe this is great news. I actually ignored that readpipe is the beast behind qw. Anyway, to quote from the post you linked to:

      The prototype of readpipe() is now ($). Previously, it was broken: $ perl5.8.8 -wle 'print prototype"CORE::readpipe"' Can't find an opnumber for "readpipe" at -e line 1. $ bleadperl -wle 'print prototype"CORE::readpipe"' $

      So an immediate observation is that -X are still "broken" (in Gabriel's own words, which thus I will take for absolutely true, and literally!) in 5.10.0 and I don't have the slightest idea in blead. Furthermore, I don't have the slightest idea of which is the beast behind them: if you check the rest of the thread @ clpmisc then you'll see that I tried with stat but evidence is it's not what "I" (actually, I'm just trying to help someone, but the matter became intriguing for me too...) was after:

      --
      If you can't understand the incipit, then please check the IPB Campaign.