I'm pretty new to perl. I have an SomeItem object that contains an array of InnerObjects, of which I want to call the "foo" method on.
foreach $obj (@ { $self->{InnerObjects} })开发者_运维知识库 {
$obj->foo();
}
This doesn't work. Here's the error I get:
Can't call method "foo" without a package or object reference
The InnerObject class is in the same file as SomeItem, and would prefer to keep it that way if possible, so how can I access the InnerObject class/package from the SomeItem class/package?
Here's how I declare the array in the constructor:
$self->{InnerObjects} = [];
and set it:
sub set {
my ($self, @items) = @_;
@{ $self->{InnerObjects} } = @items;
}
Your code so far looks legitimate. Therefore the error MAY be in the data passed to set()
.
Please add the following to set code:
sub set {
my ($self, @items) = @_;
@{ $self->{InnerObjects} } = @items;
print "OBJECT To work on: " . ref($self) . "\n";
print "TOTAL objects passed: " . scalar(@items) . "\n";
foreach my $obj (@items) { print "REF: " . ref($obj) . "\n" };
}
This will show how many objects you passed and whether they are indeed objects of correct class (ref
should print class name)
Also, please be aware that @{ $self->{InnerObjects} } = @items;
copies over the array of object references, instead of storing the reference to the original array @items
- this is NOT the reason for your problem at all but causes you to basically allocate 2 arrays instead of one. Not a major problem memory-management wise unless the array is very large, but still wasteful (@items
array would need to be garbage collected after set()
is done).
I apologize for putting what was essentially comment-content as an answer but it's too big to be a comment.
My solution to the problem ended up creating a hash that contained the ID of the SomeItem which points to a reference of an array of InnerObjects. This hash is created by the manipulating classlike so,
%SomeItemInnerObjects; # Hash of SomeItem IDs=>InnerObject array references
$SomeItemInnerObjects{ $currentSomeItem->{ID} } = \@myInnerObjects;
and gets used as follows:
foreach $item (@{ $SomeItemInnerObjects{$currentSomeItem->{ID} } }) {
# item is an InnerObject
$item->foo($currentSomeItem->{ID});
}
So SomeItem no longer contains InnerObjects. I know this doesn't answer the question per se, but presents an alternate solution.
精彩评论