dragonchild has asked for the wisdom of the Perl Monks concerning the following question:

I've got the following situation: The problem I'm having is that the function in Base can't access the information in the package of Foo or Bar.

So, I'm thinking about this and I came up with a number of possible solutions.

I guess what I'm bitching about is that even though $self is from package Foo or Bar, blah() is executing within the namespace of Base. Is there some way I can get around this? Is there another solution I'm not seeing?

------
We are the carpenters and bricklayers of the Information Age.

Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Replies are listed 'Best First'.
(tye)Re: Interesting OO/package conundrum...
by tye (Sage) on Oct 12, 2001 at 01:02 UTC

    You can use a method:

    package Foo; my %Required; BEGIN { @Required{qw(This That TheOther)}= (1)x3; } sub _GetRequired { return \%Required; } # ... package Base; sub _GetRequired { return {}; } sub isRequired { my $self = shift; my $attr = shift; return $self->_GetRequired()->{$attr}; }
    (Updated.)

            - tye (but my friends call me "Tye")
Re: Interesting OO/package conundrum...
by premchai21 (Curate) on Oct 11, 2001 at 23:15 UTC
    The second is the standard solution. The first is more kludgy IMHO. The second is what is recommended in the perldocs (perltoot IIRC).
Re: Interesting OO/package conundrum...
by runrig (Abbot) on Oct 12, 2001 at 01:12 UTC
    Is there some way I can get around this?

    Get around what? Seems like the best solution to me. One method in the base class which accesses data from the inheriting class.

(jeffa) Re: Interesting OO/package conundrum...
by jeffa (Bishop) on Oct 12, 2001 at 01:12 UTC

      Good that you referred us to that thread. This example was the best.

      To answer the original question, a solution in Perl might (with a disclaimer) look something like this:

      # NOTE: untested pseudo-code below! package Base; sub new { ... $self->{'requiredValue'} = getRequiredValue(); ... } # ensure that my child classes do things properly sub getRequiredValue { die "Subclasses must implement 'getRequiredValu +e'" } ... package Child1; sub getRequiredValue { 42 } # you know it's the answer :-) ... package Child2; sub getRequiredValue { 360 } ... package main; my ($c1, $c2); $c1 = Child1->new(); # Call trace looks like: # 1. Base::new # 2. Child1::getRequiredValue $c2 = Child2->new(); # This call trace is different: # 1. Base::new # 2. Child2::getRequiredValue !!!
Re: Interesting OO/package conundrum...
by pike (Monk) on Oct 12, 2001 at 15:13 UTC
    You could also use a class attribute on Base, rather than an instance attribute:

    package Base; my %_required = ('Foo' => {one =>1, two => 1, three =>1}, 'Bar' => {one =>1, three => 1, fourteen =>1}); sub isRequired { my ($self, $attr) = @_; my $class = ref $self; return exists $_required{$class}->{$attr}; }

    This way, you will store the hash of the required attributes only once.

    Greetings, pike

      This is an interesting idea, and one I thought about. But, I rejected it because this would require that the base class knows about the child classes, even if it's only the names. A goal for OO is that no-one knows anything more than they absolutely have to. Have a class know something about its children is, generally, a no-no. *shrugs*

      ------
      We are the carpenters and bricklayers of the Information Age.

      Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Retitle this thread: cannot access class data of derived classes in parent method
by princepawn (Parson) on Oct 12, 2001 at 19:58 UTC
    I think this title is really what you are saying.

    PRINCE "jobless business object layer designer" PAWN