Je *_*Rog 4 perl reference typeglob
$ref = \%hash;
$ref = \@hash;
Run Code Online (Sandbox Code Playgroud)
我如何使用perl中的typeglob做与引用相同的操作?
perl需要解释的具体步骤是$$ref{key}什么?
使用perlref文档*foo{THING}的Making References部分中记录的语法.
可以使用特殊语法(称为语法)创建引用
*foo{THING}.*foo{THING}返回对THING插槽的引用*foo(这是包含所有内容的符号表条目foo).Run Code Online (Sandbox Code Playgroud)$scalarref = *foo{SCALAR}; $arrayref = *ARGV{ARRAY}; $hashref = *ENV{HASH}; $coderef = *handler{CODE}; $ioref = *STDIN{IO}; $globref = *foo{GLOB}; $formatref = *foo{FORMAT};
例如:
#! /usr/bin/env perl
use strict;
use warnings;
our %hash = (Ralph => "Kramden", Ed => "Norton");
our @hash = qw/ apple orange banana cherry kiwi /;
my $ref;
$ref = *hash{HASH};
print $ref->{Ed}, "\n";
$ref = *hash{ARRAY};
print $ref->[1], "\n";
Run Code Online (Sandbox Code Playgroud)
输出:
Norton orange
至于你问题的第二部分,补充一下
print $$ref{Ralph}, "\n";
Run Code Online (Sandbox Code Playgroud)
在Ed产生预期输出之后.编译器为此行生成代码,该代码按以下顺序执行:
$ref.$ref的东西.但是不要相信我的话.要减少产量,请考虑类似的双线:
my $ref = { Ralph => "Kramden" };
print $$ref{Ralph};
Run Code Online (Sandbox Code Playgroud)
使用为调试编译的perl运行它可以获得我们的帮助
$ debugperl -Dtls ref
[...]
(ref:1) nextstate
=>
(ref:2) pushmark
=> *
(ref:2) padsv($ref) # STEP 1
=> * \HV()
(ref:2) rv2hv # STEP 2
=> * HV()
(ref:2) const(PV("Ralph"\0)) # STEP 3a
=> * HV() PV("Ralph"\0)
(ref:2) helem # STEP 3b
=> * PV("Kramden"\0)
(ref:2) print
=> SV_YES
(ref:2) leave
[...]
请注意,全局变量略有不同.
我不确定你的意图是什么,但有一些重要的警告.请注意,typeglob表示符号表条目,因此您不能以这种方式获取词汇,因为它们存在于pad中,而不是符号表中.例如,假设您在上面的代码中my @hash = ("splat");的赋值之前插入$ref.结果可能会让你大吃一惊.
$ ./prog "my" variable @hash masks earlier declaration in same scope at ./prog line 11. Norton orange
关于标量的行为也可能令人惊讶.
*foo{THING}undef如果尚未使用特定的THING,则返回,除了标量的情况.*foo{SCALAR}如果$foo尚未使用,则返回对匿名标量的引用.这可能会在将来的版本中发生变化.
告诉我们您正在尝试做什么,我们将能够为您提供具体,有用的建议.
如果你问的是如何获得类型glob的引用,它只是:
my $ref = \*symbol_name_here;
Run Code Online (Sandbox Code Playgroud)
对于它们符号的"文字名称"(即您键入符号的确切名称的位置),而不是变量.但是,你可以这样做:
my $ref = Symbol::qualify_to_ref( $symbol_name );
Run Code Online (Sandbox Code Playgroud)
对于变量符号.然而,上面的工作strict和下面的更容易的不:
my $ref = \*{$symbol_name};
Run Code Online (Sandbox Code Playgroud)
其中一个好处Symbol::qualify*是,它将包名称作为第二个变量处理.所以...
my $sref = Symbol::qualify_to_ref( $symbol_name, $some_other_package );
Run Code Online (Sandbox Code Playgroud)
做同样的事情\*{$some_other_package.'::'.$symbol_name}并且它适用strict.
一旦你有了符号ref,要获得插槽,你必须遵守引用,所以perl并不认为你试图像哈希一样使用它,就像这样.
my $href = *{ $sref }{HASH};
my $code = *{ $sref }{CODE};
my $arref = *{ $sref }{ARRAY};
my $io = *{ $sref }{IO};
Run Code Online (Sandbox Code Playgroud)
我以不同的方式将你的两个想法放在一起.如果你有一个符号表引用,你可以获得HASH插槽,这是一个引用,就像任何其他对哈希的引用一样.所以你可以做到以下几点.
或
*hash{HASH}->{key}
Run Code Online (Sandbox Code Playgroud)
要么
${ *hash{HASH} }{key}
Run Code Online (Sandbox Code Playgroud)
将工作.但这些更安全
( *hash{HASH} || {} )->{key};
${ *hash{HASH} || {} }{key};
Run Code Online (Sandbox Code Playgroud)
如果你想这样做不是直接输入,而是对表的引用,你会做以下事情:
my $ref = \*hash;
my $value = *{ $ref }{HASH} && *{ $ref }{HASH}->{key};
Run Code Online (Sandbox Code Playgroud)
注意: %hash绝对需要是一个包变量.只有包变量驻留在符号表中(因此只有subs @ISA和Exporter变量倾向于在现代符号表中).词法变量(声明的那些my)位于"pad"中.
更新:
我已经远离使用Symbol这么多了.奇怪的是,即使是核心,它似乎不规范的Perlers做的方式- 看 --things.相反,我在我所谓的"无块"中使用直接方式,就像我可以制作它们一样.
# All I want is one symbol.
# Turn strict-refs off, get it, turn it back on.
my $symb = do { no strict 'refs'; \*{$symbol_name} };
Run Code Online (Sandbox Code Playgroud)
要么
{ no strict 'refs';
*{$package_name.'::'.$symbol_name} = $sub_I_created;
... # more reckless symbol table mucking...
}
Run Code Online (Sandbox Code Playgroud)我几乎总是使用这个*STDERR{IO}成语来表示glob文件句柄.在现代Perl中,这些通常是对象.
my $fh = *STDERR{IO};
say blessed( $fh ); # IO::File
$fh->say( 'Some stuff' );
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
934 次 |
| 最近记录: |