In Perl, why can't I bless a variable that contains a literal reference?
I've been trying to learn Perl for a few days, and I am still often surprised and sometimes puzzled about how and why it does it. Here's my final riddle: why are the following two blocks of code not equivalent?
my $thing = '';
bless \$thing; # class is implicit
against
my $thing = \'';
bless $thing; # class again implicit
The second form says "Modify read-only value" on the second line.
source to share
\''
is a literal reference.
\$thing
is a link to $thing
. The value is $thing
set to an empty string at the moment.
The reason for the error you are getting is the same as the reason the following error will give you the same error:
my $thing = \5;
$$thing = 10;
bless
changes the value to which its first argument refers. In this case, and in yours, it $x
refers to something that is not being modified.
See perldoc perlobj :
Objects are blessed; Variables are not
When we
bless
do something, we do not bless the variable that contains a reference to that thing, and we do not bless the reference that the variable holds; we bless what the variable refers to (sometimes called the referent). (emphasis mine)
If you want a scalar supported class you can do this:
#!/usr/bin/env perl
use v5.10;
package MyString;
use strict; use warnings;
sub new {
my ($class, $self) = @_;
bless \$self => $class;
}
sub content { ${$_[0] }
sub length { length ${$_[0]} }
package main;
use strict; use warnings;
my $string => MyString->new("Hello World");
say $string->$_ for qw(content length);
Of course, you need to exercise discipline and not modify the instance data through the backdoor, as in $$string = "Bye bye cruel world"
.
source to share
The operator bless
works through a link: it is a referenced object that becomes blessed. Most often, the reference data is a hash, but as you discovered it can also be scalar or any other Perl data type
my $thing = '';
bless \$thing; # class is implicit
This is normal. You set $thing
to an empty string (which doesn't matter here) and you bless it by passing a reference to itbless
my $thing = \'';
bless $thing; # class again implicit
This sets a $thing
reference to the string constant, so it bless
tries to work with that constant, which is not possible because, as the post says, it is read-only
Long story short, in the first case you are blessing a scalar variable $thing
, and in the second case you are trying to bless a string constant ''
that fails
source to share