如何让Perl的ref()函数返回REF,IO和LVALUE?

时间:2009-09-09 13:54:47

标签: perl types

ref()的文档提到了几个可能的返回值。我了解其中大部分内容,但不是REFIOLVALUE。我如何编写Perl代码以使ref返回这些值?

在阅读typeglobs and file handles上的文档后,我使用此代码接近IO

open(INPUT, '<', 'foo.pl');
print ref(*INPUT{IO}), "\n";  # Prints IO::Handle

对于REFLVALUE,我尝试了几种奇怪的结构,但没有成功。

3 个答案:

答案 0 :(得分:15)

这是制作大部分内容的快捷方式:

use 5.010;
say 'SCALAR:  ', ref \undef;
say 'ARRAY:   ', ref [1..5];
say 'HASH:    ', ref { key => 'value' };
say 'CODE:    ', ref sub {};
say 'REF:     ', ref \\undef;
say 'GLOB:    ', ref \*_;
say 'LVALUE:  ', ref \substr "abc", 1, 2;
say 'LVALUE:  ', ref \vec 42, 1, 2;
say 'FORMAT:  ', ref *STDOUT{FORMAT}; # needs declaration below
say 'IO:      ', ref *STDIN{IO};   # actually prints IO::Handle
say 'VSTRING: ', ref \v5.10.0;
say 'Regexp:  ', ref qr/./;

format =
.

REF只是对另一个参考的引用。 LVALUE是标量的特例,如果被修改则会产生外部影响。

IO是句柄背后的基本类型,您可以使用Acme::Damn from CPAN使其显式显示。正如Michael Carman在评论中指出的那样,你真的不应该是不兼容的对象 - 不要在实际代码中使用。

use Acme::Damn;
say 'IO:      ', ref damn *STDIN{IO}; # really prints IO

ref函数的源代码也有一些显示“BIND”和“UNKNOWN”的代码,但是不应该有办法让那些没有搞乱内部的东西。 Blead还有一个有趣的“REGEXP”(不同于上面的“Regexp”);如果有人知道如何让ref屈服......

答案 1 :(得分:4)

REF表示您引用了引用:

my ($x, $y, $z);
$x = 1;
$y = \$x;
$z = \$y;
print ref $z;  # REF

LVALUE引用很少见,但您可以从返回左值的某些函数中获取它们。 substr是一个:

$x = 'abcdefg';
$y = \ substr($x, 0, 3);
print ref $y;  # LVALUE

IO::Handle个对象实际上是有福的IO refs:

$x = *STDIN{IO};
print ref $x;  # IO::Handle
print $x;      # IO::Handle=IO(0x12345678)

我不确定如何直接获得IO引用。

答案 2 :(得分:2)

  1. LVALUE

    perl5.8 -e '{$a = "aaa"; $b = \substr($a, 0, 2); print "$$b\n"; print ref($b)."\n"}'
    aa

    LVALUE

    这个问题在perldoc -f ref

  2. 中有解释
  3. REF

    perl5.8 -e '{$a = "aaa"; $b = \\$a; print ref($b)."\n"}'

    REF

    它基本上是对一个本身就是参考的值的引用。 做$b = \$a; $c = \$b; print ref($c)

  4. 可能会更好