2011-02-11 10 views
10

He intentado buscar esto, pero no he encontrado nada.

estoy curioso en cuanto a por qué se podría poner el asterisco en el siguiente escenario:

$var = *$self->{class_var}; 

¿Qué significa el * hacer en esta situación?

actualización

Tomé lo anterior desde el módulo Net :: Telnet y Simplemente estoy tratando de entenderlo.

El código actual es:

$s = *$self->{net_telnet}; 

Me pregunto, entonces, es el nombre del paquete net_telnet?

+1

Nunca antes había visto esa construcción, pero parece que está haciendo algo malo con typeglobs y referencias indirectas (es decir, almacenar el nombre de una variable en otra variable). * estremecimiento * –

+0

'net_telnet' no es un nombre de paquete, es algún metadata de sockethandle (para el identificador referido por' * $ self') que se almacenará en la tabla de símbolos. – mob

Respuesta

6

Desde el código corto que tengo Supongo $self tiene un typeglob. Puede acceder a los subelementos explícitamente como menciones eugene y, o implícitamente, mediante el uso de cualquier sintaxis de desreferencia estándar en typeglob.

#!/usr/bin/perl 

use strict; 
use warnings; 

our %test = (class_var => "test class_var"); 
our @test = qw(one four nine); 

my $self = \*test; 
print "Self is '$self'\n"; 

my $var1 = *{$self}{HASH}{class_var}; 
print "Var1 is '$var1'\n"; 

my $var2 = *$self->{class_var}; 
print "Var2 is '$var2'\n"; 

my $var3 = ${*{$self}}{class_var}; 
print "Var3 is '$var3'\n"; 

my $var4 = ${*$self}{class_var}; 
print "Var4 is '$var4'\n"; 

my $x_scale = *$self{ARRAY}[0]; 
print "x_scale is '$x_scale'\n"; 

my $y_scale = *$self->[1]; 
print "y_scale is '$y_scale'\n"; 

my $z_scale = ${*$self}[2]; 
print "z_scale is '$z_scale'\n"; 

referencia Typeglob (fuera de símbolo aliasing) se utilizan con más frecuencia para la ranura de IO que permite que un objeto para ser utilizado como un identificador de archivo, pero desde la typeglob sostiene uno de cada tipo de variable de las otras ranuras variables se puede usar para almacenar datos de estado adicionales.

El typeglob no tiene que ser global, Symbol::gensym puede crear un typeglob que es básicamente anónimo.

2

parece un caso de alguien haciendo algo con typeglobs; por ejemplo * $ self podría ser una subclase implementando un manejador de archivo
@Dave Sherohman, eche un vistazo a la fuente IO::Pipe. contiene un código divertido que juega un montón con typeglobs, un poco en la pregunta

3

Probablemente se trata de un objeto filehandle. El identificador de archivo se almacena en la ranura fh del globo aerostático, pero los metadatos sobre el identificador de archivo se almacenan en la ranura hash del globo.

Así que esto está diciendo

$var = *{$self}{class_var} 

es decir, la eliminación de referencias $ yo como un typeglob, y luego usarlo como un hash.

No puede hacer $ self -> {class_var} porque no es una referencia HASH, es una referencia GLOB.

use strict; 

my $fh;  

my $self = \*fh; 

*$self->{val} = 'foo'; 

he utilizado como un ejemplo $fh cosa, pero en realidad IO :: Handle (probablemente) va a utilizar alguna otra manera de crear un pegote ref. Pero con este fragmento de código que debe ver que

print ref $self; 

dice GLOB, pero todavía se puede

print *$self->{val}; 

para obtener foo.

Para leer más aquí: http://perldoc.perl.org/perldata.html#Typeglobs-and-Filehandles

3

*$var sintaxis le da acceso a un conjunto de variables globales por su nombre. Por ejemplo, $foo, @foo, %foo y *foo:

package main; 
no strict; 
$foo = 'bar';  # global variable! 
@main::foo = qw(an array); 
%foo = ('hash' => 'table'); 
open foo, '>', '/tmp/foo'; 

$self = 'foo'; 

print "\$$self is ${*$self}\n"; # $foo 
print "\@$self is @{*$self}\n"; # @foo 
print "\%$self is {", 
    (map {$_, " => ", *$self->{$_}, ","} keys %{*$self}), 
    "}\n"; 
print "Performing operations on the $self filehandle:\n"; 
print {*$self} "hello world\n"; 
close *$self; 

open X, '<', '/tmp/foo'; 
print <X>; 
close X; 

 
$foo is bar 
@foo is an array 
%foo is {hash => table,} 
Performing operations on the foo filehandle: 
hello world 

Por supuesto, en estos tiempos modernos con referencias y variables léxicas, cualquier cosa hecha con un código como éste, probablemente, se podría hacer en una mejor manera.

+0

Esta respuesta se vuelve estricta, lo que es casi seguro que no es el caso en el código en cuestión, pero sin embargo es una buena visión general del concepto global glob :) – Altreus

+0

Aún puede 'usar strict' si califica todos los nombres de variables globales - '$ foo -> $ :: foo' o' $ main :: foo'. – mob

8

En resumen, esta es una forma anticuada de pasar una referencia a un hash en la tabla de símbolos. El * antes de $self desreferencia el valor en $self como un typeglob. El ->{class_var} luego desreferencia ese typeglob como un hash, y busca la clave class_var.

Actualización:

Excavar hacia abajo a través de la jerarquía de clases revela que el objeto está siendo creado en IO::Handle con:

sub new { 
    my $class = ref($_[0]) || $_[0] || "IO::Handle"; 
    @_ == 1 or croak "usage: new $class"; 
    my $io = gensym; 
    bless $io, $class; 
} 

Symbol::gensym devuelve un typeglob completa, de los cuales se utiliza principalmente la ranura IO. Sin embargo, dado que se trata de un glosario de tipo completo, los submódulos están explotando ese hecho y almacenando sus datos en los otros campos globales, a saber, la parte HASH.

+2

+1 Buena explicación. Perldata también menciona esto: 'Esta solía ser la forma preferida de pasar matrices y hash por referencia a una función, pero ahora que tenemos referencias reales, esto rara vez se necesita. –