What exactly does Perl's "bless" do?
Asked Answered
C

9

157

I understand one uses the "bless" keyword in Perl inside a class's "new" method:

sub new {
    my $self = bless { };
    return $self;
}    

But what exactly is "bless" doing to that hash reference ?

Carnallite answered 24/12, 2008 at 19:48 Comment(1)
See "Bless My Referents" back from 1999. Looks pretty detailed. (The Perl manual entry doesn't have a great deal to say on it, unfortunately.)Nabal
F
158

In general, bless associates an object with a class.

package MyClass;
my $object = { };
bless $object, "MyClass";

Now when you invoke a method on $object, Perl know which package to search for the method.

If the second argument is omitted, as in your example, the current package/class is used.

For the sake of clarity, your example might be written as follows:

sub new { 
  my $class = shift; 
  my $self = { }; 
  bless $self, $class; 
} 

EDIT: See kixx's good answer for a little more detail.

Floe answered 24/12, 2008 at 19:58 Comment(0)
E
88

bless associates a reference with a package.

It doesn't matter what the reference is to, it can be to a hash (most common case), to an array (not so common), to a scalar (usually this indicates an inside-out object), to a regular expression, subroutine or TYPEGLOB (see the book Object Oriented Perl: A Comprehensive Guide to Concepts and Programming Techniques by Damian Conway for useful examples) or even a reference to a file or directory handle (least common case).

The effect bless-ing has is that it allows you to apply special syntax to the blessed reference.

For example, if a blessed reference is stored in $obj (associated by bless with package "Class"), then $obj->foo(@args) will call a subroutine foo and pass as first argument the reference $obj followed by the rest of the arguments (@args). The subroutine should be defined in package "Class". If there is no subroutine foo in package "Class", a list of other packages (taken form the array @ISA in the package "Class") will be searched and the first subroutine foo found will be called.

Eldwon answered 24/12, 2008 at 20:39 Comment(6)
Your initial statement is incorrect. Yes, bless takes a reference as its first argument, but it is the referent variable that is blessed, not the reference itself. $ perl -le 'sub Somepackage::foo {42}; %h=(); $h=\%h; bless $h, "Somepackage"; $j = \%h; print $j->UNIVERSAL::can("foo")->()' 42Huggermugger
Kixx's explanation is comprehensive. We should not bother with converter's picking on theoretical minutiae.Ballot
@Blessed Geek, It's not theoretical minutiae. The difference has practical applications.Velar
Old perlfoundation.org link for "inside-out object" is, at best, behind a login wall now. Archive.org link of the original is here.Potherb
Even the archive.org link doesn't work any more "due to robots.txt".Soybean
Perhaps this will serve in place of the broken link @Soybean commented on: perldoc.perl.org/perlobj.html#Inside-Out-objectsIddo
D
11

Short version: it's marking that hash as attached to the current package namespace (so that that package provides its class implementation).

Daredeviltry answered 24/12, 2008 at 19:54 Comment(0)
R
11

This function tells the entity referenced by REF that it is now an object in the CLASSNAME package, or the current package if CLASSNAME is omitted. Use of the two-argument form of bless is recommended.

Example:

bless REF, CLASSNAME
bless REF

Return Value

This function returns the reference to an object blessed into CLASSNAME.

Example:

Following is the example code showing its basic usage, the object reference is created by blessing a reference to the package's class −

#!/usr/bin/perl

package Person;
sub new
{
    my $class = shift;
    my $self = {
        _firstName => shift,
        _lastName  => shift,
        _ssn       => shift,
    };
    # Print all the values just for clarification.
    print "First Name is $self->{_firstName}\n";
    print "Last Name is $self->{_lastName}\n";
    print "SSN is $self->{_ssn}\n";
    bless $self, $class;
    return $self;
}
Revoke answered 3/6, 2016 at 12:1 Comment(0)
M
6

I will try to provide an answer here since the ones here didn't quite click for me at the time I was initially writing this(warning, this answer is fairly poorly structured, feel free to skip over the parts that are not particularly useful to you).

Perl's bless function associates the specified reference with a package name string, and making the arrow operator of the blessed reference look for the method in the package associated with the reference, and if it does not find it, it continues looking using the @ISA array if there is one(this is beyond the scope of this post).

Why would we need this?

Let's begin by expressing an example in JavaScript:

(() => {
    //'use strict'; // uncomment to fix the bug mentioned below.

    class Animal {
        constructor(args) {
            console.log(this);
            this.name = args.name;
            this.sound = args.sound;
        }
    }

    /* This is left for historical reasons, 
     *    modern JavaScript engines no longer allow you to
     *    call class constructors without using new.
     * 
     * var animal = Animal({
     *     'name': 'Jeff',
     *     'sound': 'bark'
     * }); 
     * console.log(animal.name + ', ' + animal.sound); // seems good
     * console.log(window.name); // my window's name is Jeff?
     */

    // as of recently, Animal constructor cannot be called without using the new operator.
    var animal = new Animal({
        'name': 'Jeff',   
        'sound': 'bark'
    });

    console.log(animal.name + ', ' + animal.sound); // still fine.
    console.log("window's name: " + window.name); // undefined
})();

Now let's look at the desugared version of the class construct:

(() => {
    // 'use strict'; // uncomment to fix bug.

    var Animal = function(args) {
        this.name = args.name;
        this.sound = args.sound;
        return this; // implicit context hashmap
    };
    
    /** 
     *  The bug left for historical reasons,
     *      should still work now in modern web developer consoles.
     *      
     *  var animal = Animal({
     *      'name': 'Jeff',
     *      'sound': 'Bark'
     *  });
     *  console.log(animal.name + ', ' + animal.sound); // seems good
     *  console.log("The window's name is: " + window.name); // my window's name is Jeff?
     */
  
    // the new operator causes the "this" inside methods to refer to the animal
    // rather than the global scope, so the bug mentioned above does not occur.
    var animal = new Animal({
        'name': 'Jeff',
        'sound': 'bark'
    });
    console.log(animal.sound);    
    console.log(window.name); // the name has not been changed by the constructor.
})();

The Animal's constructor function takes an Object of properties and returns an Animal with those properties, or if you forgot to put the new keyword, it will return the whole global context(which is window inside the browser developer console).

Perl has no "this" nor "new" nor "class", but it can still have a function that behaves similarly. We won't have a constructor nor a prototype, but we will be able to create new animals and modify their individual properties.

# immediatly invoked subroutine execution(IIFE).
(sub {
    my $Animal = (sub {
        return {
            'name' => $_[0]{'name'},
            'sound' => $_[0]{'sound'}
        };
    });

    my $animal = $Animal->({
        'name' => 'Jeff',
        'sound' => 'bark'
    });

    print $animal->{sound};
})->();

Now, we have a problem: What if we want the animal to perform the sounds by themselves rather than having to print what their voice is directly. That is, we want a function performSound that prints the animal's own sound.

One way to do this is by giving each instance of an Animal its own performSound subroutine reference.

# self contained scope 
(sub {
    my $Animal = (sub {
        $name = $_[0]{'name'};
        $sound = $_[0]{'sound'};
    
        return {
            'name' => $name,
            'sound' => $sound,
            'performSound' => sub {
                print $sound . "\n";
            }
        };
    });

    my $animal = $Animal->({
        'name' => 'Jeff',
        'sound' => 'bark'
    });

    $animal->{'performSound'}();
})->();

This is usually not what we want because performSound is put as a completely new subroutine reference for each animal that is constructed. Constructing 10000 animals would potentially allocate 10000 performSound subroutines. We want to have a single subroutine performSound that is used by all Animal instances that look up their own sound and print it.

(() => {
    'use strict';

    /* a function that creates an Animal constructor which can be used to create animals */
    var Animal = (() => {
        /* function is important, as fat arrow does not have "this" and will not be bound to Animal. */
        var InnerAnimal = function(args) {
            this.name = args.name;
            this.sound = args.sound;
        };
        /* defined once and all animals use the same single function call */
        InnerAnimal.prototype.performSound = function() {
            console.log(this.name);
        };
        
        return InnerAnimal;
    })();
 
    var animal = new Animal({
        'sound': 'bark',
        'name': 'Jeff'
    });
    animal.performSound(); // Jeff
})();

Here is where the parallel to Perl kinda stops.

JavaScript's new operator is not optional, without it, "this" inside object methods contaminates the global scope:

(() => {
    // uncommenting this prevents unintentional
    //     contamination of the global scope, and throws a TypeError instead.
    // 'use strict'; 

    var Person = function() {
        this.name = "Sam";
    };
//    var wrong = Person(); // oops! we have overwritten window.name or global.main.
//    console.log(window.name); // my window's name is Sam?
    var correct = new Person; // person's name is actually stored in the person now.    
})();

We want to have one function for each Animal that looks up that animal's own sound rather than hardcoding it at construction.

Blessing lets us use the package's subroutines rather than having to attach a subroutine ref to each object, it also makes ref refer to the more meaningful package name(such as Animal) as the name for the what the object is rather than a boring HASH or whatever other referent you chose to bless:

package Animal;
sub new {
    my $packageRef = $_[0];
    my $name = $_[1]->{'name'};
    my $sound = $_[1]->{'sound'};

    my $this = {
        'name' => $name,
        'sound' => $sound
    };   
    
    bless($this, $packageRef);
    return $this;
}

# all animals use the same performSound to look up their sound.
sub performSound {
    my $this = shift;
    my $sound = $this->{'sound'};
    print $sound . "\n";
}

package main;
my $animal = Animal->new({
    'name' => 'Cat',
    'sound' => 'meow'
});

print("The animal's ref is: " . ref($animal) . "\n");
$animal->performSound();

Summary/TL;DR:

  1. Perl has no "this", "class", nor "new".

  2. Blessing an object to a package gives that object a reference to the package.

  3. Using the arrow operator to invoke a method of a blessed referent($blessedObject->method(...arguments)) is often the same as calling Package::method($blessedObject, ...arguments), but if method is not found, it will continue looking using the @ISA of the package which is beyond the scope of this post.

  4. You can in fact create new classes at runtime, as long as you either violate strict 'refs' or use eval, here's a demonstration of how it can be done:

#!/usr/bin/perl

use warnings;
use strict;

print('Enter the name for the class(eg Greeter): $ ');
my $class_name = <>;
chomp $class_name;

print('Enter the name of the method(eg greet): $ ');
my $method_name = <>;
chomp $method_name;

no strict 'refs';
# The line below violates strict 'refs'.
*{$class_name . '::new'} = sub {
    my $self = bless {}, $_[0];
    return $self;
}; 
use strict 'refs';

no strict 'refs';
# The line below violates strict 'refs'
*{$class_name . '::' . $method_name} = sub {
    print("Hello, World!\n");
};
use strict 'refs';

my $instance = ($class_name)->new();
$instance->$method_name();

Why the confusion?:

One reason why bless is confusing is because there are effectively three ways of calling a package

  1. Through A::a(), as a package subroutine.
  2. Through A->a(), as a package subroutine, but that gets __PACKAGE__ passed as the first argument implicitly before the other arguments.
  3. Through $a->a() with a blessed $a into A.

The code below illustrates this:

# | Illustrates catching 3 distinct ways of calling a package's member.
package Test;

sub new {        
    return bless {}, __PACKAGE__;
}

sub runTest {
    if (ref($_[0]) eq __PACKAGE__) {
        # | $_[0] is the blessed reference.
        # | Despite being called with "->", $_[1] is NOT "Test"(__PACKAGE__).
        print("Test::runTest was called through a blessed reference call(\$instance->runTest().\n");
    } elsif ($_[0] eq __PACKAGE__) {
        # | $_[0] is "Test"(__PACKAGE__), but we can't determine for sure whether it was -> or ::.
        print("Test::runTest was called through Test->runTest() or through Test::runTest() with 'Test' as the first argument.\n");
    } else {
        # | $_[0] is neither a blessed reference nor "Test"(__PACKAGE__), so it can't be an arrow call.
        print "Test::runTest was called through Test::runTest()\n";
    }
}

package main;

my $test = Test->new();
$test->runTest();
Test->runTest();
Test::runTest();
Test::runTest('Test'); # <- Same as "Test->runTest();"
Test::runTest($test); # <- Same as "$test->runTest();"

Another reason is that unlike JavaScript, Python, which can have multiple classes with different name but different definitions/methods/properties, Perl classes have unique(ref $obj), as there can only be one package with a specific name at any given time, and @ISA takes a bit to get used to.

My final reason is that packages are less tangible than classes in other scripting languages where you can store a reference to the class itself inside a variable through the assignment operator, whereas in Perl not only can you not store references to the class(you can only refer to packages through their name strings), but trying to refer to a package through a name stored inside a variable (eg String[$method]) seems impossible without violating strict 'refs' or using eval.

Anyway hopefully somebody will find this post useful.


Note: this is a fairly old attempt at an answer, I have tried to clean up the amount of naive and embarassing/pointless/distracting statements, and adding more useful examples to help understand the concept, but it is still far from what I would like it to be(it is still fairly frustrating to re-read). I leave it as I still believe it may be of use to someone.

Please take it with a gain of salt, I apologize for any headache called by the poorly laid out structure of the answer.

Missive answered 26/8, 2016 at 22:24 Comment(3)
It is not impossible to create new classes at runtime. my $o = bless {}, $anything; will bless an object into the $anything class. Similarly, {no strict 'refs'; *{$anything . '::somesub'} = sub {my $self = shift; return $self->{count}++}; will create a method named 'somesub' in the class named in $anything. This is all possible at runtime. "Possible", however, doesn't make it a great practice to wield in every-day code. But it is useful in building object overlay systems such as Moose or Moo.Gorlovka
interesting, so you are saying I can bless a referent into a class whose name is decided at runtime. Seems interesting, and does void my unfortunately it makes it impossible(to my understanding) to create "new classes" at runtime claim. I guess my concern ultimately boiled down to it being significantly less intuitive to manipulate/introspect the package system at runtime, but so far I have failed showing anything it inherently cannot do. Package system seem to support all the tools needed to add/remove/inspect/modify itself at runtime.Missive
This is correct; you can manipulate Perl's symbol table programatically, and therefore can manipulate Perl's packages, and a package's members at runtime, even without having declared "package Foo" anywhere. Symbol table inspection and manipulation at runtime, AUTOLOAD semantics, subroutine attributes, tieing of variables to classes... there are many ways to get under the hood. Some of them are useful for autogenerating APIs, validation tools, autodocumenting APIs; we can't predict all the use cases. Shooting oneself in the foot is also a possible outcome of such trickery.Gorlovka
B
5

What specifically distinguishes a bless-ed referent is that it gets additional internal content: the SV for the reference (stored in the scalar) picks up an additional FLAGS value (OBJECT), and there is a STASH which carries the package name (with a few other differences)

perl -MDevel::Peek -wE'
    package Pack  { sub func { return { a=>1 } } }; 
    package Class { sub new  { return bless { A=>10 } } }; 
    $vp  = Pack::func(); print Dump $vp;   say"---"; 
    $obj = Class->new;   print Dump $obj'

Prints, with the same (and irrelevant for this) parts suppressed

SV = IV(0x12d5530) at 0x12d5540
  REFCNT = 1
  FLAGS = (ROK)
  RV = 0x12a5a68
  SV = PVHV(0x12ab980) at 0x12a5a68
    REFCNT = 1
    FLAGS = (SHAREKEYS)
    ...
      SV = IV(0x12a5ce0) at 0x12a5cf0
      REFCNT = 1
      FLAGS = (IOK,pIOK)
      IV = 1
---
SV = IV(0x12cb8b8) at 0x12cb8c8
  REFCNT = 1
  FLAGS = (PADMY,ROK)
  RV = 0x12c26b0
  SV = PVHV(0x12aba00) at 0x12c26b0
    REFCNT = 1
    FLAGS = (OBJECT,SHAREKEYS)             <--
    STASH = 0x12d5300   "Class"            <--
    ...
      SV = IV(0x12c26b8) at 0x12c26c8
      REFCNT = 1
      FLAGS = (IOK,pIOK)
      IV = 10

With that it is known to the interpreter that

  • this is an object

  • what package it belongs to

and this informs its use.

For example, when dereferencing that variable ($obj->name) a sub with that name is sought in the package (or hierarchy), the variable ("object") is passed as the first argument, etc.

Bequest answered 21/11, 2019 at 8:51 Comment(0)
B
0

I Following this thought to guide the development object-oriented Perl.

Bless associate any data structure reference with a class. Given how Perl creates the inheritance structure (in a kind of tree) it is easy to take advantage of the object model to create Objects for composition.

For this association we called object, to develop always have in mind that the internal state of the object and class behaviours are separated. And you can bless/allow any data reference to use any package/class behaviours. Since the package can understand "the emotional" state of the object.

Brancusi answered 5/5, 2015 at 10:59 Comment(1)
Here are same announces with how Perl works with namespaces of packages and how work with states registered in your namespace. Because this exist pragmas like use namespace::clean. But try to keep things simpler possible.Brancusi
M
0

bless($obj,'PackageName') is a Perl builtin function to give $obj access to all 'PackageName' subs

For example:

use JSON;

#-- create json data
$data = {foo=>"bar"};

#-- lets print stringify using JSON
print JSON::encode_json($data);
    # will print: {"foo":"bar"}

#-- let create object
$obj = { "xxx" => "yyy" };

#-- let try bless obj with JSON
bless($obj,'JSON');

#-- $obj still has "xxx"
print $obj->{xxx};
    #will print yyy

#-- see above JSON has sub encode_json, now in $obj has all JSON subs
#-- include encode_json lest try:

print $obj->encode_json($data);

   #-- error: Usage: JSON::XS::encode_json(scalar)
   # why ?

   # because $obj->encode_json is same as:
   
   # JSON::encode_json($obj,$data)

   # using $obj->mysub is set $obj as FIRST ARGUMENT of PackageName::mysub 
   # and this encode_json try to stringify $obj that already 
   # have all subs of package JSON
Mattah answered 13/4, 2023 at 7:21 Comment(0)
L
-9

For example, if you can be confident that any Bug object is going to be a blessed hash, you can (finally!) fill in the missing code in the Bug::print_me method:

 package Bug;
 sub print_me
 {
     my ($self) = @_;
     print "ID: $self->{id}\n";
     print "$self->{descr}\n";
     print "(Note: problem is fatal)\n" if $self->{type} eq "fatal";
 }

Now, whenever the print_me method is called via a reference to any hash that's been blessed into the Bug class, the $self variable extracts the reference that was passed as the first argument and then the print statements access the various entries of the blessed hash.

Longlimbed answered 16/6, 2011 at 5:39 Comment(2)
@darch From which source was this answer plagiarized?Koweit
@AndersonGreen perl.com/pub/1999/09/refererents.htmlPollock

© 2022 - 2024 — McMap. All rights reserved.