in reply to exists(&subname) causes strange autovivification problem

> I don't think exists(&subname) should "autovivify" anything.

Complex things are happening here, and I don't know in which order to untangle them

Compare my code experiments.

use strict; use warnings; use feature 'say'; no autovivification; use Data::Dump qw/pp/; my @ary; pp exists $::{non}; pp exists $::{other}; pp exists (&non) ; push @ary, exists (&non) ; say scalar(@ary)

1 # *non exists after compilation of &non "" # *other doesn't exist () # sub &non doesn't exist but empty list returned 0 # @ary has consequently no elements
Edit
After commenting out #no autovivification

1 "" "" 1

Update

My guess is that there is actually always an autovivification happening at compile time creating the glob, which has side effects on exists at run time.

I'd say this implementation is buggy!

If you need a workaround, I'd try to first checking if the glob exists before checking the slot and avoiding exists &name

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

Replies are listed 'Best First'.
Re^2: exists(&subname) causes strange autovivification problem (workaround)
by LanX (Saint) on Nov 06, 2024 at 01:21 UTC
    > If you need a workaround, I'd try first checking if the glob exists before checking the slot and avoiding exists &name

    I have no words to express how f*cked *p typeglobs are!!!

    If only a sub is using the symbol, then the coderef is stored directly where the glob is supposed to be.

    (Larry gets a spanking next time we meet ;)

    Anyway this code seems to work in all edge cases, only tested on mobile phone yet.

    use strict; use warnings; use feature 'say'; no autovivification; use Data::Dump qw/pp/; sub sub_exists{ my $name = shift; return exists $::{$name} # symbol exists && ( ref $::{$name} eq "CODE" # only code || (*{$::{$name}}{CODE} && 1) # also code || !1 # false ); } for my $name (qw/zero one two three/) { pp { $name => sub_exists($name) }; } our $one=1; our $two=2; sub two {2}; sub three {3}

    { zero => "" } { one => "" } { two => 1 } { three => 1 }

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

    TODO

    Extend code to cover subs in other namespaces than main

      So don't use them!

      sub sub_exists { my $name = shift; no strict qw( refs ); return exists( &$name ); }

      Bonus: Not limited to subs in the current namespace.

      To avoid the bug the OP identified, place the sub outside of scope of no autovivification;, or add use autovivification; to it.

      sub sub_exists { my $name = shift; no strict qw( refs ); use autovivification; # Disable module to avoid bug. return exists( &$name ); }
Re^2: exists(&subname) causes strange autovivification problem
by ysth (Canon) on Nov 06, 2024 at 00:08 UTC
    Note that my $x = [ exists &nonesuch ]; doesn't seem to have the problem. That makes it even more confusing.
    --
    A math joke: r = | |csc(θ)|+|sec(θ)| |-| |csc(θ)|-|sec(θ)| |
      Sorry I was still composing the post on my mobile phone

      Testing inside termux and copy pasting to browser is sometimes complicated.

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