7

I am looking into Perl OO (new to Perl). I created a trivial example hierarchy:
Parent class:

#!usr/bin/perl  
use strict;  
use warnings;  

package Objs::Employee;  

my $started;  

sub new {  
    my ($class) = @_;  
    my $cur_time = localtime;  
    my $self = {  
        started => $cur_time,  
    };
    print "Time: $cur_time \n";  
    bless $self;  
}  

sub get_started {  
    my ($class) = @_;  
    return $class->{started};  
}  

sub set_started {  
    my ($class, $value) = @_;  
    $class->{started} = $value;  
}  

1;  

Child class:

#!/usr/bin/perl  
package Objs::Manager;  
use strict;  
use warnings;  

use base qw (Objs::Employee);  

my $full_name;  

sub new {  
    my ($class, $name) = @_;  
    my $self = $class->SUPER::new();  
    $self->{full_name} = $name;  
    return $self;     
}  

1;  

I try to test it as follows:

#!/usr/bin/perl  
use strict;  
use warnings;  


use Objs::Manager;  

my $emp = Objs::Manager->new('John Smith');  
use Data::Dumper;  
print Dumper($emp); 

Result:

Time: Sun Sep 29 12:56:29 2013

$VAR1 = bless( {
                 'started' => 'Sun Sep 29 12:56:29 2013',
                 'full_name' => 'John Smith'
               }, 'Objs::Employee' );

Question: Why is the object reported in the dump an Obj::Employee and not an Obj::Manager?
I called new on a Manager.

Cratylus
  • 52,998
  • 69
  • 209
  • 339
  • 1
    By the way, since the methods `get_started` and `set_started` are instance methods (unlike `new` which is a class method), the first argument to them will be an instance of the class, not the class itself. So you should call it `$self` or something to avoid confusion. – David Knipe Sep 29 '13 at 11:59
  • The $started package variable in Objs::Employee is unused. – Alexander Hartmaier Oct 21 '13 at 19:53

1 Answers1

11

Always use two arguments for bless, as $class tells into which package should object be blessed. If $class is omitted, the current package is used.

bless $self, $class; 

output

$VAR1 = bless( {
             'started' => 'Sun Sep 29 13:24:26 2013',
             'full_name' => 'John Smith'
           }, 'Objs::Manager' );

From perldoc -f bless:

Always use the two-argument version if a derived class might inherit the function doing the blessing

mpapec
  • 50,217
  • 8
  • 67
  • 127
  • Why?Could you please elaborate? – Cratylus Sep 29 '13 at 11:24
  • In my example the `$class` is a passed-in argument which I would expect to be Manager since I did: `Objs::Manager->new`. So the `$self` but itself is what the super constructor returns which is an Employee and the bless downcasts it? – Cratylus Sep 29 '13 at 11:30
  • Class is always first parameter in constructor (static method). When called from child then child class is passed, otherwise it is current class. Note that `$class` inside your child and parent are different variables having different values. – mpapec Sep 29 '13 at 11:34
  • 2
    Even if `$class` is `Objs::Manager` in the call to `Objs::Employee->new` (which I'm not disputing), it's a moot point because you haven't used `$class` anyway. But because you haven't used the second argument to `bless`, it defaults to the current package, which is set by the line `package Objs::Employee;`. – David Knipe Sep 29 '13 at 11:55