An update to looking at the symbol table

In the chapter “Symbol Tables and Typeglobs”, I show some tricks to look at the symbol table to see which variables are there. I ended the chapter with a short example of Package::Stash, but in updating an answer to the Stackoverflow questions [How can I list all variables that are in a given scope?](https://stackoverflow.com/a/79771517/2766176), I came up with a better example, and one that does a better job of handling variable names that

use v5.12;

package Local {
	my $package = 'Local::';

	our $foo;
	our @bar;
	}

vars_in( 'main' );
vars_in( 'Local' );

sub vars_in {
	state $rc = require Package::Stash;
	my( $package ) = @_;

	my $stash = Package::Stash->new($package);

	my @list = $stash->list_all_symbols;

	say $package;
	foreach my $symbol ( sort @list ) {
		next if $symbol =~ /::\z/;
		(my $printable_symbol = $symbol) =~ s/([\x00-\x1F\x7F])/control_char_to_str($1)/ge;
		say "  $printable_symbol";

		foreach my $sigil ( qw($ @ % &), '' ) {
			my $var = "$sigil$symbol";
			(my $printable_var = $var) =~ s/([\x00-\x1F\x7F])/control_char_to_str($1)/ge;
			say "    has $printable_var" if $stash->has_symbol($var);
			}
		}
	}

sub control_char_to_str {
    my $char = shift;
    my $ord = ord($char);
    return '^?' if $ord == 127;  # DEL
    return '^' . chr($ord + 64);
    }

New to “Symbol Tables”

“Symbol Tables” has always been a tough chapter because it’s the part of the book where I have the least experience, I think. I’m not strong on Perl internals and don’t have to think about symbol tables so much; my terminology is a bit soft and pudgey here.

For the most part, the chapter is the same without major changes. I use the word “stash” much more, flesh out some examples, and show the output of more programs.

I made a mistake in the previous edition. I had a subroutine that would check for that a package variable had been used somewhere in the program. I can do that with something like:

print "Used!\n" if *foo{ARRAY};

The typeglob will return a reference to the data for that variable, and references are always true values. If @foo hasn’t been used (so, no data yet, even if it’s the empty list), this returns undef. It returns true even if I’ve undef-ed the array; I’ve still used the array already in that case.

However, for scalars, it always returns a reference. It even returns a reference in the case that the scalar of that name has not ever been used or seen. The means *foo{SCALAR} is true for all names all the time. perlref says:

*foo{THING} returns undef if that particular THING hasn’t been used yet, except in the case of scalars. *foo{SCALAR} returns a reference to an anonymous scalar if $foo hasn’t been used yet. This might change in a future release.

Besides that, I made adjustments for imprecisions in my previous explanations and terms. I could use a good set of tech reviewers on it still.

At the end of the chapter, after showing all of the complicated stuff, I show Package::Stash, which mostly makes it easier to do the really hard stuff.

Check out this chapter in O’Reilly Atlas.