why "Bless" in OO Perl
Anonymous Monk
created: 2006-05-03 02:09:40

Hi all,

I don't understand, what "bless" function does, and what will be the output, I have analysed many books, but I am not satisfied with the explanations, kindly explain with examples.

Thank you.

Re: why "Bless" in OO Perl
created: 2006-05-03 02:18:32

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.


Dave

Re^2: why "Bless" in OO Perl
created: 2006-05-03 09:13:28

Actuall the thing being referenced is blessed; the reference is still just a reference. The blessing changes the referent, not the reference itself. A new reference taken to the same referent will exhibit blessed / object-y behavior.</pedant>

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.

Re^3: why "Bless" in OO Perl
created: 2006-05-03 11:37:08

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*


Dave

Re^4: why "Bless" in OO Perl
created: 2006-05-03 13:34:50
OO: extending a closure object was an example of using a closure as an object base type. The blessed sub is the only possible accessor. It allowed the object to be very opaque, but I didn't see it as enough of a benefit to recommend it.

Caution: Contents may have been coded under pressure.
Re^4: why "Bless" in OO Perl
created: 2006-05-03 13:54:26

Not brlliant but see node 128123 for a method of accessing the source for a coderef without resorting to B:: trickery (of course it's not perfect since it doesn't preserve closureness, but then that's a hard problem no matter what . . .).

Update: Never mind, that's not blessing the coderef directly it's overloading &{}. I thought I'd done something similar with blessed coderefs. Hrmm . . .

Re: why "Bless" in OO Perl
created: 2006-05-03 02:24:46

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.

--
brian d foy
Subscribe to The Perl Review
Re^2: why "Bless" in OO Perl
created: 2006-05-03 12:21:30

The class name is really attached to the object of the reference. That is just rarely seen because the object is usually scoped to the constructor's code block, so it doesn't get observed in the wild. Example code shows this in my reply below.

After Compline,
Zaxo

Re: why "Bless" in OO Perl
created: 2006-05-03 03:21:02

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

Re: why "Bless" in OO Perl
created: 2006-05-03 03:27:59

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.

After Compline,
Zaxo

Re: why "Bless" in OO Perl
created: 2006-05-03 05:41:16
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

Re: why "Bless" in OO Perl
created: 2006-05-03 11:10:29
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"

Re: why "Bless" in OO Perl
created: 2006-05-03 11:27:29
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.
Re: why "Bless" in OO Perl
created: 2006-05-03 19:28:43
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. [doc://bless|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.

perlmonks.org content © perlmonks.org and Anonymous Monk, brian_d_foy, davido, Fletch, grinder, hesco, ikegami, mikasue, PreferredUserName, Roy Johnson, Zaxo

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03