Re: why "Bless" in OO Perl
by davido (Cardinal) on May 03, 2006 at 06:18 UTC
|
bless causes the reference contained in its first parameter to become an object of the class specified in the second argument. The reference is essentially "blessed into a class.", or possibly more descriptively, "promoted", or "reborn" into a class.
Before being blessed, a reference is just a reference. After being blessed, it's an object instance of a particular class.
If you're looking for a good book on the subject, I highly recommend merlyn's "Alpaca book", Learning Perl Objects, References & Modules.
| [reply] |
|
|
use strict;
{package Foo; sub oik { print "oik\n" } }
my $x = bless [], "Foo";
$x->oik;
our @y;
*y = $x;
( \@y )->oik;
Zaxo's explanation below shows this as well.
| [reply] [d/l] |
|
|
You are absolutely correct. ...it's a concept I understand but have difficulty expressing clearly, especially in a layman vocabulary. Good job with the linguistic deobfuscation. ;)
I might add, the referent needn't be a hash, a simple scalar, nor an array. It could also be a file handle, a regexp, and even a sub, though I've never figured out a useful purpose to blessing a sub. Now I'm sure someone will follow-up with a brilliant use of this technique. *grin*
| [reply] |
|
|
|
|
Re: why "Bless" in OO Perl
by brian_d_foy (Abbot) on May 03, 2006 at 06:24 UTC
|
bless attaches a class name to a reference. When I call a method on the reference, Perl looks in that class to find the method.
The return value is just the reference, now with the class label attached to it. See the bless entry in perlfunc for the details.
| [reply] [d/l] [select] |
|
|
| [reply] |
Re: why "Bless" in OO Perl
by Zaxo (Archbishop) on May 03, 2006 at 07:27 UTC
|
I think it's easiest to see what bless does by constructing an object and method without any module or package. Here's a bare-bones object with a single method.
# a method - get/set the value
sub Foo::value () :lvalue { ${$_[0]} }
# make three references to two things
my ($foo, $bar) = (do { my $v = 1; \$v }) x 2; # 2 refs to same $v
my $baz = do { my $v = 1; \$v }; # different $v
# . . . and a fourth
my $quux = bless $foo, 'Foo';
printf "\$foo\t%s\n\$bar\t%s\n\$baz\t%s\$quux\t%s\n",
$foo, $bar, $baz, $quux;
print 'value is ', $foo->value(), $/;
$bar->value() = 10;
print 'now, ', $quux->value(), $/;
__END__
$foo Foo=SCALAR(0x80591e8)
$bar Foo=SCALAR(0x80591e8)
$baz SCALAR(0x8059248)
$quux Foo=SCALAR(0x80591e8)
value is 1
now, 10
Notice that $bar got blessed, too, though we didn't do a thing to $bar itself. $baz escaped, having its own thing to point to.
So, we see what bless does. It takes a reference and an identifier string, and marks what the reference points to as an object tagged by the identifier. That identifier is used in looking for methods by checking the symbol table for the tag and looking under it for subs.
| [reply] [d/l] |
Re: why "Bless" in OO Perl
by grinder (Bishop) on May 03, 2006 at 07:21 UTC
|
Here's another datapoint. Let's have a look at what a blessed object looks like, compared to an ordinary one.
% perl -MDevel::Peek -e 'Dump({}), Dump(bless({}, "Pkg")); '
SV = RV(0x807d01c) at 0x8057b38
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x805716c
SV = PVHV(0x805c720) at 0x805716c
REFCNT = 2
FLAGS = (SHAREKEYS)
IV = 0
NV = 0
[... needless detail omitted ...]
SV = RV(0x807d01c) at 0x80572d4
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x805716c
SV = PVHV(0x805c720) at 0x805716c
REFCNT = 2
FLAGS = (OBJECT,SHAREKEYS)
IV = 0
NV = 0
STASH = 0x8057238 "Pkg"
[... needless detail omitted ...]
Both are scalars, the first holds a reference to an anonymous hash, the other holds a reference of an anonymous hash that has been blessed (or attached) to a package.
See how the SV (scalar value) structure has an extra bit flipped in its FLAG field that indicates it is an object, and also how the name of the class is recorded too.
Armed with this information, the interpreter then can take a method call on the scalar, and go and find out what code to run from where.
• another intruder with the mooring in the heart of the Perl
| [reply] [d/l] |
Re: why "Bless" in OO Perl
by hesco (Deacon) on May 03, 2006 at 09:41 UTC
|
Blessing a data structure _into_ a class associates that data structure with the ->methods (subroutines) of the class. If permits you to call those methods on that data. That is to say, bless turns a reference to a data structure into an object.
An object gives (or at least should give) you a black box routine, with a predictable and stable interface. You should be able to invoke $object->methods on the object (and the blessed reference to a data structure) without having to know the details of what happens inside the black box (class or package). By adding to that an understanding of inheritance, it is possible to use Modules (packages, classes), and to inherit methods from those modules. This is because the constructors (the ->new() methods) of those modules return a "blessed" reference that associates that module's methods (subroutines) with the referenced data structure, giving you direct access to all that code in the use'd module.
Someone around here has a sig file pointing out that 90% of every perl script has already been written. That 90% are the modules (cpan or home grown) upon which you build a specific application.
-- Hugh | [reply] |
Re: why "Bless" in OO Perl
by ikegami (Patriarch) on May 03, 2006 at 23:28 UTC
|
I found the earlier answers rather complex. It's easy to explain by showing what happens if you don't.
{
package MyClass;
sub new { my ($class) = @_;
my $self = {};
return $self; }
sub test { print("Hi!"); }
}
my $o = MyClass->new();
$o->test();
outputs
Can't call method "test" on unblessed reference
Because the hash has not been associated with a package, Perl doesn't know which test you meant to call. bless is the means by which you create this association.
{
package MyClass;
sub new { my ($class) = @_;
my $self = {};
bless($self, $class); # Added
return $self; }
sub test { print("Hi!"); }
}
my $o = MyClass->new();
$o->test();
outputs
Hi!
So how do Java and C++ work without something like bless? It's a combination of having constructors and of the finer grain of their type systems.
| [reply] [d/l] [select] |
Re: why "Bless" in OO Perl
by mikasue (Friar) on May 03, 2006 at 15:10 UTC
|
I think of it as an adoption. When you bless a reference into a class it's like adopting a kid into a family and letting him take your last name. So the kid will remain a kid but can now be called YOUR kid and be called by your last name :-)
Am I on track monks?
Kid - John
Family - Johnson
bless (John, Johnson) "bless john to be a johnson now" | [reply] |
Re: why "Bless" in OO Perl
by PreferredUserName (Pilgrim) on May 03, 2006 at 15:27 UTC
|
To add a different spin on the good answers already
here, the call:
my $object = bless($reference, "MyClass");
does something like this:
sub bless {
my ($reference, $class) = @_;
$reference->{class_name} = $class;
return $reference;
}
and then whenever Perl sees something like this:
$object->some_function($arg1);
it transforms it into this:
$object->{class_name}::some_function($object, $arg1);
which in this case would translate into:
MyClass::some_function($object, $arg1);
There's a little more to it than that, to support
inheritance and such, but that's the general idea. | [reply] [d/l] [select] |