Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

using passed parent object reference to get at attributes

by previous (Sexton)
on Dec 19, 2015 at 23:18 UTC ( [id://1150778]=perlquestion: print w/replies, xml ) Need Help??

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

#on line 27 how do I use what I think's a cParent obj ref to get at it's "test" attribute
{ package cParent; sub new { my $class = shift; my $self = {}; bless( $self, $class + ); #std line $self->{sub_passed_to_parent}=shift; $self->{test_att}=3; $self->{oChild}=cChild->new( $self, $self->{sub_passed_to_pare +nt} ); return $self; } } { package cChild; sub new { my $class = shift; my $self = {}; bless( $self, $class + ); #std line $self->{parent_obj_ref}=shift; $self->{sub_passed_to_child}=shift; print "in new for cChild and just calling sub_passed_to_child\ +n"; $self->{sub_passed_to_child}( $self->{parent_obj_ref} ); return $self; } } sub passed_sub { print "yes in passed_sub\n"; my $oParent_ref=shift; print "\$oParent_ref is $oParent_ref\n"; print "\$oParent_ref->{test_att} is $oParent_ref->{test_att}\n"; +#How do I access attribute {test_att} properly } print "going in\n"; my $oParent=cParent->new(\&passed_sub);

Replies are listed 'Best First'.
Re: using passed parent object reference to get at attributes
by GrandFather (Saint) on Dec 20, 2015 at 00:34 UTC

    Not sure what you are trying to do, but the following may suggest some things to think about. You may also be interested in Not quite an OO tutorial for a light weight introduction to Perl OO.

    use strict; use warnings; package cParent; sub new { my ($class) = @_; my $self = bless {test_att => 3}, $class; return $self; } sub parent_sub { my ($self) = @_; print "In parent. Test value is $self->{test_att}\n"; } package cChild; push @cChild::ISA, 'cParent'; sub child_sub { my ($self) = @_; print "In child_sub. Test value is $self->{test_att}\n"; } package main; my $obj = cChild->new(); $obj->child_sub(); $obj->parent_sub();

    Prints:

    In child_sub. Test value is 3 In parent. Test value is 3

    If the reply is way off base maybe you need to tell us more about what you are trying to achieve.

    Premature optimization is the root of all job security

      I wondered about doing "use parent" instead of working with @ISA for the test case. I didn't know but it turns out you can if the Perl isn't really ancient (I think you need 5.10.1). Instead of:

      push @cChild::ISA, 'cParent';
      one could also:
      use parent -norequire, 'cParent';

      In the real application, as opposed to the test example, the classes are probably broken up into seperate files and you probably just remove the '-norequire, '.

      Ron
        @ISA is something I knew nothing about so thanks for raising it as a possibility...I see it's "Each package contains a special array called @ISA . The @ISA array contains a list of that class's parent classes, if any. This array is examined when Perl does method resolution, which we will cover later. " Thank you for the education!
      Thank you for you're reply...and question re what I'm trying. The object within an object is a proxy for a combo box that I've made i.e. the list box is in the parent object and the child object is a TK entry widget that I've "enhanced" and that is useful in it's own right. The combo boxes will be used in clusters and whilst there's some similarity in their functionality (locked away in the objects) I wanted to customise them by passing in a non-oop subroutine that gets called when a key is pressed in the entry (child object). To this end I'm passing the non-oop customising subroutine into the parent object to pass onto the child object upon it's creation along with a reference to the parent object. This is so the child object (entry) can call the custom subroutine and supply it with the parent object's reference when the entry's custom bindtag fires. I could reference the combo's directly 'cos they created in main just like the non-oop sub but wonder how you'd pass a combo reference internally...for future reference i.e. I can get around this but in a not very oop-way. Hope that explains
Re: using passed parent object reference to get at attributes
by NetWallah (Canon) on Dec 20, 2015 at 00:34 UTC
    Your posted code runs fine for me, and prints "3" as the parent's test attribute value.

    Output:

    going in in new for cChild and just calling sub_passed_to_child yes in passed_sub $oParent_ref is cParent=HASH(0xf18038) $oParent_ref->{test_att} is 3
    So - you are doing it right !

    If you wanted to pass the CHILD, instead of the parent at:

    ##OLD $self->{sub_passed_to_child}( $self->{parent_obj_ref} ); $self->{sub_passed_to_child}->( $self ); ##New, explicitly d +e-ref the sub
    Then passed_sub would look like:
    sub passed_sub { print "yes in passed_sub\n"; my ($child) = @_; # I don't like using shift here.. print $child->{parent_obj_ref}{test_att}; # 3
    Of course, it would be "better", to use a "getter", so typos would be checked at compile time. </c>

            "I can cast out either one of your demons, but not both of them." -- the XORcist

      >So - you are doing it right ! Yes I just re-ran it and to my amazement I am. WOW I was half watching the Strictly come dancing final so that might have impaired my judgement and I made a few changes right at the end but missed that this had solved my problem...Thanks for the confirmation and extra advice. I'd been struggling with how to organise this for a while in the "big" program so this little test has done the business. Thanks.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1150778]
Front-paged by BrowserUk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (9)
As of 2024-04-18 17:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found