2011-02-11 37 views
10

Tôi đã cố gắng tìm kiếm điều này, nhưng đã không tìm thấy gì cả.

Tôi chỉ tò mò là tại sao người ta sẽ đặt dấu hoa thị trong kịch bản dưới đây:

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

Gì * làm trong tình huống này?

Cập nhật

tôi lấy trên từ các module Net :: Telnet và tôi chỉ đơn giản là cố gắng để hiểu nó.

Mã thực tế là:

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

Tôi tự hỏi, sau đó, là net_telnet tên gói?

+1

Tôi chưa bao giờ thấy cấu trúc đó trước đây, nhưng có vẻ như nó đang làm điều gì đó Ác với typeglobs và tham chiếu gián tiếp (tức là lưu trữ tên biến trong biến khác). * rùng mình * –

+0

'net_telnet' không phải là tên gói, nó là một số siêu dữ liệu sockethandle (đối với tay cầm được tham chiếu bởi' * $ self') được lưu trữ trong bảng ký hiệu. – mob

Trả lời

6

Từ đoạn mã ngắn mà bạn có, tôi giả sử $self giữ một typeglob. Bạn có thể truy cập các phần tử con một cách rõ ràng như các đề cập eugene y, hoặc ngầm sử dụng bất kỳ cú pháp dereference tiêu chuẩn nào trên 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"; 

Typeglob tài liệu tham khảo (bên ngoài của biểu tượng răng cưa) thường được sử dụng nhiều nhất cho các khe IO cho phép một đối tượng được sử dụng như một tập tin xử lý, nhưng kể từ khi typeglob giữ một trong mỗi loại biến các khe biến khác có thể được sử dụng để lưu trữ dữ liệu trạng thái bổ sung.

typeglob không phải là toàn cục, Symbol::gensym có thể tạo một typeglob về cơ bản là ẩn danh.

2

trông giống như trường hợp ai đó làm điều gì đó với typeglobs; ví dụ * $ tự có thể là một lớp con triển khai một tệp xử lý
@Dave Sherohman, hãy xem nguồn của IO::Pipe. nó chứa một số mã vui nhộn chơi rất nhiều với typeglobs, một chút trong câu hỏi

3

Điều này khá có thể đối phó với một đối tượng tập tin. Filehandle chính nó được lưu trữ trong khe fh của glob, nhưng siêu dữ liệu về filehandle được lưu trữ trong khe băm của glob.

Vì vậy, đây đang nói

$var = *{$self}{class_var} 

ví dụ dereferencing $ tự như một typeglob, và sau đó sử dụng nó như là một băm.

Bạn không thể thực hiện $ self -> {class_var} vì nó không phải là ref của HASH, đó là ref GLOB.

use strict; 

my $fh;  

my $self = \*fh; 

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

Tôi đã sử dụng $fh làm ví dụ chuyện, nhưng trên thực tế IO :: Xử lý (có thể) sẽ sử dụng một số cách khác tạo ra một ref glob. Nhưng với đoạn mã này bạn sẽ thấy rằng

print ref $self; 

nói GLOB, nhưng bạn vẫn có thể

print *$self->{val}; 

để có được foo.

Đọc thêm ở đây: http://perldoc.perl.org/perldata.html#Typeglobs-and-Filehandles

3

*$var cú pháp cung cấp cho bạn truy cập vào một tập hợp các biến toàn cầu bằng tên. Ví dụ, $foo, @foo, %foo, và *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 

Tất nhiên, trong những thời hiện đại với sự tham khảo và các biến từ vựng, bất cứ điều gì thực hiện với mã như thế này có thể có thể được thực hiện trong một cách tốt hơn.

+0

Câu trả lời này tắt nghiêm ngặt, gần như chắc chắn không phải là trường hợp trong mã được đề cập, nhưng vẫn là một tổng quan tốt về toàn bộ khái niệm toàn cầu :) – Altreus

+0

Bạn vẫn có thể 'sử dụng nghiêm ngặt 'nếu bạn đủ điều kiện cho tất cả các tên biến chung - '$ foo -> $ :: foo' hoặc' $ main :: foo'. – mob

8
%main::some_hash = (class_var => 'xyz'); 

my $self = *main::some_hash; 

print *$self->{class_var}, "\n"; # prints 'xyz' 

Tóm lại, đây là cách cổ xưa để truyền tham chiếu đến băm trong bảng biểu tượng. Các * trước khi $self tham chiếu giá trị trong $self dưới dạng typeglob. Sau đó, ->{class_var} sau đó là các tham số mà typeglob làm băm và tra cứu khóa class_var.

Cập nhật:

Đào xuống thông qua hệ thống phân cấp lớp cho thấy rằng đối tượng đang được tạo ra trong IO::Handle với:

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

Symbol::gensym trả về một typeglob hoàn chỉnh, trong đó khe IO được sử dụng chủ yếu. Tuy nhiên, vì nó là một typeglob đầy đủ, các mô-đun phụ đang khai thác thực tế đó và lưu trữ dữ liệu của chúng trong các trường glob khác nhau, cụ thể là phần HASH.

+2

+1 Giải thích hay. Perldata cũng đề cập đến điều này: 'Đây là cách ưa thích để truyền mảng và băm bằng cách tham chiếu vào một hàm, nhưng bây giờ chúng ta có những tham chiếu thực sự, điều này hiếm khi cần thiết. –

Các vấn đề liên quan