8

I am working on updating some very old Perl code (not my code) and I came across the following in a subroutine:

sub DoEvent {
   local(*eventWEH, $foreachFunc, @args) = @_;
   $ret = do $foreachFunc(*eventWEH, @args);
}

This seemed to work fine in Perl 5.6.1 but no longer works in Perl 5.22 which gives a syntax error just after the do $foreachFun(

What is the purpose of the asterisk in front of the variable *eventWEH?

If this were "C" I would suggest some sort of pointer. Any suggestions?

ETA: This sub gets called with lots of different types for the first parameter. For example:

 &DoEvent($abc, "DoAbc", @args);

and

 &DoEvent(@xyz, "DoXyz", @args);

So as per the answers given, it looks like the *eventWEH can take on a different data type to match whatever parameter is passed to the sub.

user3276159
  • 199
  • 1
  • 8
  • Are you sure it's not `&DoEvent(\$abc, "DoXyz", @args)` and `&DoEvent(\@xyz, "DoXyz", @args)`? What you posted doesn't make much sense. – ikegami Mar 03 '16 at 19:28

4 Answers4

15

The syntax error has nothing to do with the globs (the symbols with the asterisk sigil). The syntax error is due to the removal of do $func(LIST) in 5.20. Replace

$ret = do $foreachFunc(*eventWEH, @args);

with

$ret = $foreachFunc->(*eventWEH, @args);

As for your literal question, *foo is a typeglob, or glob for short. A glob is a proxy of an instance of the following C structure:

struct gp {
    SV *        gp_sv;          /* scalar value */
    struct io * gp_io;          /* filehandle value */
    CV *        gp_cv;          /* subroutine value */
    U32         gp_cvgen;       /* generational validity of cached gp_cv */
    U32         gp_refcnt;      /* how many globs point to this? */
    HV *        gp_hv;          /* hash value */
    AV *        gp_av;          /* array value */
    CV *        gp_form;        /* format value */
    GV *        gp_egv;         /* effective gv, if *glob */
    PERL_BITFIELD32 gp_line:31; /* line first declared at (for -w) */
    PERL_BITFIELD32 gp_flags:1;
    HEK *       gp_file_hek;    /* file first declared in (for -w) */
};

Globs are primarily used internally, though some file handles are primarily accessed via named globs (*STDIN, *STDOUT and *STDERR), and they are used to create aliases (*foo = \&bar;).

ikegami
  • 367,544
  • 15
  • 269
  • 518
3

It is namespace symbol sigil that contains all other types. In older Perl code it is usually used to work with file handles. Modern Perl should use simple scalars - i.e. $.

Oleg V. Volkov
  • 21,719
  • 4
  • 44
  • 68
2

It is a glob, which directly accesses symbol table. This way you can access a variable without referring to type (or, any type with that name), for example. There is rarely a reason that you'd have to use it in Perl nowadays.

Here are some references on symbol table, an interesting use of it, and a bit of an overview. Books "Programming Perl" and "Mastering Perl" have an authorative coverage.

Community
  • 1
  • 1
zdim
  • 64,580
  • 5
  • 52
  • 81
2

In the old days, you'd have to use a typeglob to pass around a file handle, like here:

# eventWEH is a global filehandle
open( eventWEH, $filename ) or die "Couldn't open $filename: $!";
somefunc( *eventWEH );

But nowadays you have proper lexical filehandles, so you can do

my $event_fh;
open( $event_fh, '<', $filename ) or die "Couldn't open $filename: $!";
somefunc( $event_fh );
Andy Lester
  • 91,102
  • 13
  • 100
  • 152
  • In the current days, we still use typeglobs to pass around file handles. We just store references to them in scalars. `print("$event_fh\n");`. – ikegami Mar 03 '16 at 19:17
  • We don't need to, though. We could place a file handle directly into a scalar. `perl -e'my $fh = \*STDOUT; print($fh "$fh\n"); $fh = *$fh{IO}; print($fh "$fh\n");'` – ikegami Mar 03 '16 at 19:23