Можно ли передавать ссылки на объекты Perl между модулями? - PullRequest
1 голос
/ 21 декабря 2011

Пример кода:

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;

Когда яtry call $testClass1->testRef, $testClass2Ref=undef.

Как передать ссылку на объект от родителя?

Обновить

Ой, извините, я пропустил строку в конструкторах примера.

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

Этот тест работает, но отладчик Eclipse показывает эти переменные как undef.

Спасибо за помощь.

Ответы [ 3 ]

2 голосов
/ 21 декабря 2011

Помимо синтаксических ошибок, вы не используете режим strict. Включение этого параметра покажет, что $self не объявляется ни в одном из пакетов. Заменив:

bless $self, $class;

с:

my $self = bless {}, $class;

Все проходит как положено.

1 голос
/ 21 декабря 2011

Можно ли передавать ссылки на объекты Perl между модулями?

Абсолютно! * * 1005

В этом тестовом скрипте я создаю два класса, один для тестирования и один для тестирования. Помните, что объекты - это просто ссылки, а методы - просто подпрограммы; используйте их таким же образом.

#!/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();

РЕДАКТИРОВАТЬ: Теперь используется более современная система, MooseX::Declare (которая основана на Moose) с Method::Signatures. Это значительно экономит базовый шаблон и позволяет вам сосредоточиться на том, что вы хотите, чтобы объекты делали, а не на том, как они реализованы.

#!/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();

Для более реалистичных случаев посмотрите, как некоторые более крупные модульные системы передают объект, представляющий сложные понятия. С головы до головы, HTTP::Response объект обходит все вокруг через LWP систему

1 голос
/ 21 декабря 2011

Когда вы исправляете синтаксические ошибки, это работает.

> ./test.pl
> Test 2

Вы пропустили

my $self = {};

в обоих new методах.

Полезным инструментом является

perl -wc testClass1.pm
...