Lexa
Lexa

Reputation: 11

Can one pass Perl object references between modules?

Example code:

testClass1.pm

package testClass1; 
{
my $testClass2Ref;

sub new
{
    my($class) = shift;
    $testClass2Ref= shift;
    bless $self, $class;
    return $self;}
}

sub testRef
{
    $testClass2Ref->testRef;
}
}

testClass2.pm

package testClass2; 
{

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

sub testRef
{
    print "Test 2";
}
}

test.pl

use testClass1;
use testClass2;

my $testClass2 = testClass2->new();
my $testClass1 = testClass2->new($testClass2);
$testClass1->testRef;

When I try call $testClass1->testRef, $testClass2Ref=undef.

How can I pass reference on the object from parent?

Update

Oh, sorry, I missed string in example's constructors.

sub new
{
    my($class) = shift;
    $testClass2Ref = shift;
    my $self    = {name=>'testClass1'};
    bless $self, $class;
    return $self;
}

This test is working, but Eclipse debugger show this variables as 'undef'.

Thanks for your help.

Upvotes: 1

Views: 3826

Answers (3)

Joel Berger
Joel Berger

Reputation: 20280

Can one pass Perl object references between modules?

Absolutely!

In this test script I make two classes, one that tests and one to be tested. Remember objects are just references and methods are just subroutines; use them in the same way.

#!/usr/bin/env perl

use strict;
use warnings;

package Tester;

sub new {
  my $class = shift;
  my ($other) = @_;

  my $self = { other => $other };
  bless $self, $class;

  return $self;
}

sub examine { 
  my $self = shift; 
  print "I'm holding a: ", ref( $self->{other} ), "\n";
}

package Candidate;

sub new { return bless {}, shift }

package main;

my $candidate = Candidate->new();
my $tester = Tester->new( $candidate );

$tester->examine();

EDIT: Now using a more modern system, MooseX::Declare (which is based on Moose) with Method::Signatures. This saves a lot of the boilerplate and lets you focus on what you want the objects to do, rather then how they are implemented.

#!/usr/bin/env perl

#technically Moose adds strict and warnings, but ...
use strict;
use warnings; 

use MooseX::Declare;
use Method::Signatures::Modifiers;

class Tester {
  has 'other' => ( isa => 'Object', is => 'rw', required => 1 );

  method examine () {
    print "I'm holding a: ", ref( $self->other() ), "\n";
  }
}

class Candidate { }

no MooseX::Declare;

package main;

my $candidate = Candidate->new();
my $tester = Tester->new( other => $candidate );

$tester->examine();

For more realistic cases, see how some larger module systems pass object representing complex concepts. Off the top of my head, HTTP::Response object get passed around all through the LWP system

Upvotes: 1

niczero
niczero

Reputation: 367

When you fix the syntax errors it works.

> ./test.pl
> Test 2

You were missing

my $self = {};

in both new methods.

A useful tool is

perl -wc testClass1.pm

Upvotes: 1

Richard Simões
Richard Simões

Reputation: 12801

Besides the syntax errors, you aren't using strict mode. Turning it on will reveal that $self isn't being declared in either package. By replacing:

bless $self, $class;

with:

my $self = bless {}, $class;

Everything goes through as expected.

Upvotes: 2

Related Questions