0

I am looking into the IO:Socket.pm module and I see the first time the "*$sock" notation.

sub socket {
    @_ == 4 or croak 'usage: $sock->socket(DOMAIN, TYPE, PROTOCOL)';
    my($sock,$domain,$type,$protocol) = @_;

    socket($sock,$domain,$type,$protocol) or
        return undef;

    ${*$sock}{'io_socket_domain'} = $domain;
    ${*$sock}{'io_socket_type'}   = $type;
    ${*$sock}{'io_socket_proto'}  = $protocol;

    $sock;
}

What is the intent of the following syntax ?

${*$sock}{'io_socket_domain'} = $domain;

Especially I am referring to the asterisk notation ... $sock is an object as far I understand but what is this thing: ${*$sock} ? And how is this asterisk operator called and its purpose?

I would be grateful if someone can make me see with some practical minimalistic example.

Ashkan Mobayen Khiabani
  • 33,575
  • 33
  • 102
  • 171
user2050516
  • 760
  • 2
  • 5
  • 15

2 Answers2

2

In summary: because filehandles (and hence socket filehandles in this case) are GLOB refs and not HASH refs. You can't simply

$sock->{field}

because that would only work if $sock is a HASH reference. Instead, for GLOB-based objects we use the hash slot of the underlying glob as a place to store the object instance fields

   $sock       # is a GLOB reference
  *$sock       # is the underlying GLOB
%{*$sock}      # is the hash at the HASH slot of the GLOB
${*$sock}{key} # is a member of the HASH
LeoNerd
  • 8,344
  • 1
  • 29
  • 36
1

IO::Handle (and therefore IO::Socket, IO::File, etc) returns a blessed typeglob reference from its constructor. This allows the object itself to be used as a filehandle, as in:

use IO::File;

$fh = IO::File->new();
if ($fh->open("< file")) {
    print <$fh>;
    $fh->close;
}

In IO::Socket, the blessed typeglob also holds a hash. ${*$sock}{'io_socket_domain'} is dereferencing the typeglob (just like @$arrayref would dereference an array reference) then accessing this hash.

RobEarl
  • 7,862
  • 6
  • 35
  • 50