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

Any solutions to this problem that have arisen since 2006? Yesterday I misspelled a subroutine. My program crashed at runtime. I don't want to write a test that does a "can" on every darned subroutine I call in my program.

I understand why Perl "can't" do this (see thread linked below). But it seems bizarre to me that it "can't" do this because some fairly rare programs dynamically write and name a subroutine. That can't happen very often.

In a world of "use strict" there is no similar pragma for this situation?

https://www.perlmonks.org/?node_id=549550

(Edited 2024-12-16 at 13:39 ET, to specify the desired behavior, as suggested in a comment: I'd like to be able to have an error produced at compile time rather than at run time.)

  • Comment on Misspelled subroutine name -- no way to catch it at compile time? C'mon.

Replies are listed 'Best First'.
Re: Misspelled subroutine name -- no way to catch it at compile time? C'mon.
by hippo (Archbishop) on Dec 16, 2024 at 16:01 UTC
    But it seems bizarre to me that it "can't" do this because some fairly rare programs dynamically write and name a subroutine. That can't happen very often.

    The counter example in the thread you linked is not that. It is that a module which exports or even just provides a given sub may only be dynamically loaded at runtime. This happens more often than you appear to presume.

    If your test suite doesn't have 100% coverage then this is the sort of thing that will bite you occasionally. The only guaranteed solution is ... improve the coverage of your test suite. Not the advice you wanted to hear, no doubt.


    🦛

Re: Misspelled subroutine name -- no way to catch it at compile time? C'mon.
by LanX (Saint) on Dec 16, 2024 at 17:44 UTC
    > My program crashed at runtime. I don't want to write a test that does a "can" on every darned subroutine I call in my program.

    Than use AUTOLOAD to catch the call before crashing.

    You haven't told us which behavior you expect, so like this you're free to implement it yourself...

    Update

    To catch a typo at compile time, drop the parens

    See Re^3: How to identify incorrect subroutine calls in a perl program

    Generally it's better to import the sub too, instead of a full qualified call.

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

      For best results, use use v5.28;/no feature qw( indirect );/no indirect; along with omitting parens. If you don't, omitting parens won't always detect the problem at compile-time, and new weird issues could be introduced.

Re: Misspelled subroutine name -- no way to catch it at compile time? C'mon.
by Haarg (Priest) on Dec 17, 2024 at 09:35 UTC
Re: Misspelled subroutine name -- no way to catch it at compile time? C'mon.
by LanX (Saint) on Dec 16, 2024 at 20:40 UTC
    > (Edited 2024-12-16 at 13:39 ET, to specify the desired behavior, as suggested in a comment: I'd like to be able to have an error produced at compile time rather than at run time.)

    Like I already updated, you can drop the parentheses (and &-sigils if any) to enforce compile time checking.

    FWIW: If you want this to happen with parentheses too, it's theoretically possible to write a module/pragma parsing the OP tree at the CHECK or UNITCHECK phase to abort compilation in case of absent subs in the namespaces. (See perlmod for phases)

    I think I know how to implement this particular feature, but that's none of my itches to scratch. 🤷🏻‍♂️

    Maybe worth checking CPAN before reinventing the wheel 🛞 (I haven't)

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

Re: Misspelled subroutine name -- no way to catch it at compile time? C'mon.
by karlgoethebier (Abbot) on Dec 17, 2024 at 16:18 UTC
Re: Misspelled subroutine name -- no way to catch it at compile time? C'mon.
by ikegami (Patriarch) on Dec 17, 2024 at 04:08 UTC

    Avoiding parens introduces new issues. It seems to me a third-party module could check that all non-method calls call a defined sub. Also, does perlcritic have a relevant rule?

Re: Misspelled subroutine name -- no way to catch it at compile time? C'mon.
by sectokia (Friar) on Dec 17, 2024 at 04:59 UTC

    Its not a matter of how often people write it: The syntax allows it, so its not a syntax error. This has a deeper meaning than you think - because it is not possible to detect this problem unless in the scope of an execution. Consider this:

    my $name = 'est'; *{$name} = sub { print "hello\n"; }; est();

    Even if strict is on, who is to say the assignment of the glob doesn't happen under the scope of no strict 'refs';? You could argue that anything you don't personally use... should be a syntax error?