Michael
Michael

Reputation: 455

Extending an Object in Perl

I've got a base object called RuleObject and an object that inherits from that called RuleObjectString. I have a new method in RuleObjectString that I want to call in my code that uses that object. But I get the error. 'Can't locate object method "compare" via package "RuleObject" at ./testobject.pl line 10.' But I'm not creating a RuleObject. I'm creating a RuleObjectString. What am I doing wrong here?

testobject.pl

  1 #! /usr/bin/perl
  2
  3 use strict;
  4
  5 use RuleObjectString;
  6
  7 my $s = RuleObjectString->new();
  8 $s->value('stuff goes here');
  9
 10 if ($s->compare('stuff')){
 11         print "MATCH!\n";
 12 }else{
 13         print "no match :(\n";
 14 }

RuleObject.pm

package RuleObject;

our @ISA = qw/Exporter/;
our @EXPORT = qw/new/;

use strict;

sub new{
        my $class = shift;

        my $self;
        $self->{value} = undef;

        bless $self;
        return $self;
}

sub value{
        my $self = shift;
        my $value = shift;
        if ($value){
                $self->{value} = $value;
        }else{
                return $self->{value};
        }
}

RuleObjectString.pm

package RuleObjectString;

our @ISA = qw/RuleObject/;
our @EXPORT = qw/compare/;

use strict;

sub compare{
        my $self = shift;
        my $compareto = shift;

        return $self->value() =~ /$compareto/;
}

Upvotes: 9

Views: 4461

Answers (3)

toreau
toreau

Reputation: 660

This is 2012, so you should consider using proper OOP solutions instead of reinventing the wheel all over again.

By using Moose, the solution would look something like this (untested):

RuleObject.pm

package RuleObject;
use Moose;

has 'value' => ( isa => 'Str', is => 'rw', required => 0, default => '' );

1;

RuleObjectString.pm

package RuleObjectString;
use Moose;

extends 'RuleObject';

sub compare {
    my $self      = shift;
    my $compareto = shift;

    return $self->value =~ /$compareto/;
}

1;

Simple! :)

Upvotes: 4

mob
mob

Reputation: 118695

I think jmcneirney is on the right track. In your RuleObject constructor, you say

bless $self;

which is the same as

bless $self, __PACKAGE__;

or

bless $self, 'RuleObject'

but what you want is for the object to blessed as a RuleObjectString. So what you want to do is say

bless $self, $class

Now

RuleObject->new()
RuleObjectString->new()

will both call the same constructor, but the object returned by the first call will be blessed as a RuleObject and the second object will be blessed as a RuleObjectString.

Upvotes: 12

jmcneirney
jmcneirney

Reputation: 1384

Try dumping the object and see what it is.

print Dumper( $s )

It's going to be a RuleObject.

You might need to define a new() in RuleObjectString and have it call Super::new().

Upvotes: 0

Related Questions