Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Problem to inspect scalars in STASH

by LanX (Chancellor)
on Feb 15, 2012 at 04:14 UTC ( #953831=perlquestion: print w/replies, xml ) Need Help??
LanX has asked for the wisdom of the Perl Monks concerning the following question:


I'm trying to inspect the symbols of a package and filter which arrays, hashes, scalars and subs where used.

This works pretty fine for all slots of a glob but for scalars!

Normally unused slots are undef or hold a reference to the corresponding type. (see ARRAYs)

But unused scalar slots automatically hold \undef which is not distinguishable from using them and setting them to undef.

DB<191> *PCKG::unknown{ARRAY} => undef DB<192> @PCKG::foo=(1,2,3) => (1, 2, 3) DB<193> *PCKG::foo{ARRAY} => [1, 2, 3] DB<194> *PCKG::foo{SCALAR} # why \undef and not undef ??? => \undef DB<195> $PCKG::foo=undef => undef DB<196> *PCKG::foo{SCALAR} # same effect => \undef DB<198> undef $PCKG::foo => undef DB<199> *PCKG::foo{SCALAR} # again => \undef

Any idea how to solve this?

Cheers Rolf

Replies are listed 'Best First'.
Re: Problem to inspect scalars in STASH
by educated_foo (Vicar) on Feb 15, 2012 at 05:08 UTC
    Yes, this is annoying, and even more so when defined(@array) and defined(%hash) become deprecated. The solution I came up with is to use defined($$name) for scalars, and defined(*{$name}{THING}) for the others. I think it works on all current Perls without polluting the stash, e.g.
    main @> $Test::x = 1; @Test::y = qw(2 3); %Test::z = (a => 'b'); main @> keys %Test:: y x z main @> join ' ', "SCALARS:", grep defined(${"Test::$_"}), keys %Test: +: 'SCALARS: x' main @> join ' ', "ARRAYS:", grep defined(*{"Test::$_"}{ARRAY}), keys +%Test:: 'ARRAYS: y' main @> join ' ', "HASHES:", grep defined(*{"Test::$_"}{HASH}), keys % +Test:: 'HASHES: z' main @> join ' ', "SCALARS:", grep defined(${"Test::$_"}), keys %Test: +: 'SCALARS: x'
      Thanks for your help... :)

      > The solution I came up with is to use defined($$name) for scalars,

      Sorry, that's not a solution because it excludes all declared package variables which became undef in the meantime.

      Think of something like  $flag = () in the middle of the code. I'm trying to fix the tab-expansion in the perldebugger, actually $f#TAB# lists all symbols starting with f, no matter which slot is used.

      DB<223> sub flo {} => 0 DB<224> $f # type TAB $f $find $flag $flo

      As a workaround I could include all symbols where only the scalar slot is defined, but if someone decides to have equally named sub &flo AND scalar $flo where the latter is undef, I can't tell if the scalar belongs to the code or not.

      While this cases seems rare enough - most people tend to use different names for different sigils - it's not a 100% solution.

      If there is no better suggestion, I will need to parse the code to reliably find all scalars.

      >Yes, this is annoying,

      FWIW I consider this behavior a bug.

      Cheers Rolf

        You're right, of course, and I agree that the SCALAR auto-vivification thing is a bug. I remember discussing this with some P5P folks awhile back, and IIRC this auto-creation of the SCALAR slot was fairly well-baked into the core. Still, you think that wandering through the symbol table should be easy -- it's just a hash of GLOBs, right? -- and then you run into all this stuff. *sigh*
Re: Problem to inspect scalars in STASH
by ikegami (Pope) on Feb 15, 2012 at 04:38 UTC
    There's no problem. Those globs indeed have a populated scalar slot.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://953831]
Approved by ikegami
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (1)
As of 2017-08-17 02:36 GMT
Find Nodes?
    Voting Booth?
    Who is your favorite scientist and why?

    Results (277 votes). Check out past polls.