4

The documentation for ref() mentions several possible return values. I understand most of them, but not REF, IO, and LVALUE. How would I write Perl code to cause ref to return those values?

After reading the documentation on typeglobs and file handles, I came close for IO with this code:

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

For REF and LVALUE I tried several bizarre constructions, but had no success.

Ether
  • 53,118
  • 13
  • 86
  • 159
FMc
  • 41,963
  • 13
  • 79
  • 132

3 Answers3

15

Here's a quick and easy way to produce most of them:

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 is just a reference to another reference. LVALUE is a special case of a scalar that has an external influence if it is modified.

IO is the base type behind the handles, you can make it appear explicitely using Acme::Damn from CPAN. As noted by Michael Carman in the comments, you really shouldn't be unblessing objects — don't use in real code.

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

The source for the ref function also has bits of code to display "BIND" and "UNKNOWN", but there shouldn't be a way to get those without messing with the internals. Blead also has an interesting unblessed "REGEXP" (different from the "Regexp" above); if someone knows how to make ref yield that...

JB.
  • 40,344
  • 12
  • 79
  • 106
  • 2
    As delightful as the name `damn` is, it's unlikely that you'll want to remove the blessing. Use `Scalar::Util::reftype()` to see past the `bless` to the underlying reference type. – Michael Carman Sep 09 '09 at 15:20
  • Damn! I forgot about Scalar::Util! :-D Unfortunately, I can't seem to use it to make `ref` return "IO". I'll add a warning about `damn` not being serious; thanks for the reminder. – JB. Sep 09 '09 at 15:33
4

REF means that you have a reference to a reference:

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

LVALUE refs are rare, but you can get them from certain functions that return lvalues. substr is one:

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

IO::Handle objects are actually blessed IO refs:

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

I'm not sure how to get an IO ref directly.

Brad Gilbert
  • 33,846
  • 11
  • 78
  • 129
Michael Carman
  • 30,628
  • 10
  • 74
  • 122
2
  1. LVALUE

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

    LVALUE

    This one is explained in perldoc -f ref

  2. REF

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

    REF

    It's basically a reference to a value that is itself a reference. Probably would have been better to do $b = \$a; $c = \$b; print ref($c)

Brad Gilbert
  • 33,846
  • 11
  • 78
  • 129
DVK
  • 126,886
  • 32
  • 213
  • 327