Reputation: 1671
I've been trying to learn Perl for a few days, and am still frequently surprised and sometimes mystified at how and why it does things. Here is my latest puzzle: why are the following two blocks of code not equivalent?
my $thing = '';
bless \$thing; # class is implicit
versus
my $thing = \'';
bless $thing; # class again implicit
The second form says "Modification of a read-only value attempted" on the second line.
Upvotes: 3
Views: 697
Reputation: 118128
\''
is a reference to a literal.
\$thing
is a reference to $thing
. The value of $thing
is set to the empty string at the moment.
The reason for the error you are getting is the same as the reason the following will give you the same error:
my $thing = \5;
$$thing = 10;
bless
modifies the thing to which its first argument refers. In this case, and in yours, $x
refers to something that is not modifiable.
See perldoc perlobj:
Objects Are Blessed; Variables Are Not
When we
bless
something, we are not blessing the variable which contains a reference to that thing, nor are we blessing the reference that the variable stores; we are blessing the thing that the variable refers to (sometimes known as the referent). (emphasis mine)
If you want a class backed by a scalar, 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 instance data through the backdoor as in $$string = "Bye bye cruel world"
.
Upvotes: 5
Reputation: 126722
The bless
operator works through a reference: it is the referenced object that becomes blessed. Most often the referenced data is a hash, but as you've found it may also be a scalar or any other Perl data type
my $thing = '';
bless \$thing; # class is implicit
This is fine. You are setting $thing
to an empty string (which is irrelevant here) and you are blessing it by passing a reference to it to bless
my $thing = \'';
bless $thing; # class again implicit
This sets $thing
to a reference to a string constant, so the bless
is then attempting to work on that constant which is impossible because, as the message says, it is read-only
In short, in the first case you are blessing the scalar variable $thing
while in the second case you are trying to bless string constant ''
which fails
Upvotes: 4