develooper Front page | perl.perl5.porters | Postings from November 2022

Re: undeclared named subs/subrefs under strict

Thread Previous | Thread Next
November 22, 2022 18:50
Re: undeclared named subs/subrefs under strict
Message ID:
Thank you for the thorough explanation, Yves. Some minor follow up:

On Tue, Nov 22, 2022 at 6:34 AM demerphq <> wrote:

> sub do_something_recursive_with_a_closure {
>     my ($self, @args)= @_;
>     local *recursive= sub { shift @args; recursive() if @args };
>     recursive();
> }

> In this case the recursive() sub doesn't exist except at run time. Or
> even if it did, it wouldnt be the recursive() sub being called by this
> code. Early binding would make that troublesome or impossible.

That is kind of my point, that such code can be a bit confusing,
especially when debugging. Isn't this why __SUB__ was created, to make it
clearer / less error-prone?

Please note I'm not arguing it *shouldn't* work. I'm just wondering whether
there should be a warning/strict level that would advise that "this may not
do what you think it does", one that could easily be dropped just like we
do 'no strict "refs"', 'no warnings "uninitialized"', etc.

> > On a somewhat related note, how would one detect if a named
> subroutine/subref was declared or not (it's ok if it was declared but is
> empty) at runtime? Right now I'm doing:
> One way is to treat the package as a class, and ask if it "can" do
> something. Assuming its not also a class and does not have an established
> @ISA then it should be fine:
> if (UNIVERSAL::can("Package", "name")) { ... }

That's really nice, but it won't cut it for my purposes. If you say
something like: my $x = \&i_dont_exist, I want to check if $x points to an
actual subroutine or to an undefined symbol.

> I have to wonder tho, *why* do you want to do this? Usually the
> correct way to see if a function is defined /is to call it/.  :-) Why
> do you want to know in advance? It feels like you are asking an XY

I'm trying to implement that "feature" (detect if a named subref is there
at any given moment without calling it) basically to help in linting /
debugging / code reviews. I was bit by this a few days ago when I made a
typo on a named ref that was imported. When I tried dumping the variable, I
got "sub { ... }" so I thought it was ok. Only when I deparsed it I saw it
as "sub;" and figured out what was wrong.

Maybe I'm being unnecessarily zealous. But since perl gives warning/error
messages on undeclared variables and barewords, I wondered if it made sense
to also get one for undeclared named subrefs in order to, mainly, detect
typos. This is another reason why it was posted here and not perlmonks, but
I'll try to avoid "how to" questions here in the future, nonetheless.


Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About