Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

perl how to determine the type of a "raw symbol"

Tags:

perl

typeglob

Apparently, it's possible to store a "raw symbol" (as opposed to a reference to a symbol) in a scalar variable and use it in scalar contexts.

How do you determine whether a scalar-valued expression is one of these symbols?

They appear to stringify to "*name_of_symbol" and ref returns "". However Data::Dumper is also able to determine that it isn't a string and prints it without quoting.

Is it possible to determine when you have a raw symbol? How is Data::Dumper doing it?

#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;

local *foo = \4;

my $sym = *foo;

printf "((%s))\n", $sym;
printf "[[%s]]\n", (ref $sym);
print Dumper($sym);

produces:

((*main::foo))
[[]]
$VAR1 = *::foo;

I was expecting some dedicated value for ref $sym.

like image 646
Gregory Nisbet Avatar asked May 17 '18 03:05

Gregory Nisbet


1 Answers

*foo is called a typeglob, or glob for short. A glob is reflection of an instance of a C structure that contains a slot for each type of value —a "glob" of "types", one might say— and forms the basis of the symbol table.

They are weird because they are both a type of variable (*foo) and a type of value (value of $sym), though this isn't relevant here.

To determine if a value is a glob, you can use the following:

use Scalar::Util qw( reftype );

( reftype(\$sym) // '' ) eq 'GLOB'

You could also use

ref(\$sym) eq 'GLOB'   # Fooled by bless(\$sym, 'GLOB')
like image 131
ikegami Avatar answered Nov 12 '22 07:11

ikegami