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

Once again here is the new version of my new() method.
sub new { my ($self, $tn, $key, $value); my $class = shift; if ($_[2] =~ /^\d+$/) { # this suppose no %hash key is all numeric $tn = Telephone::Number->new(shift, shift, shift); } else { $tn = Telephone::Number->new(shift); } my ($smstext, %hash) = @_; $self = bless { 'tn' => $tn, 'smstext' => $smstext, 'cookie_jar' => exists $hash{cookie_jar} ? delete $hash{cookie_jar} : "lwpcookies.txt", }, $class; @{$self}{keys %{$tn}} = @{$tn}{keys %{$tn}}; @{$self}{keys %hash} = @hash{keys %hash}; #dragonchild suggest +ion $self; }
Now i have created a new Telephone::Number object (temporary namespace) cause i need it to do some dirty work parsing phone numbers... but this is not the point.
With the line @{$self}{keys %{$tn}} = @{$tn}{keys %{$tn}}; i got a copy of the values of $self->{tn} in $self, but that's not what i want. I'd like to have in %{$self} aliases to the hash variables in %{$self->{tn}} so that when i change $self->{some_key_from_tn} i change also $self->{tn}->{some_key_from_tn}
I hope i explained what i need, maybe just a bit confused.
Thanks for advice.
Giulio

Edit kudra, 2001-10-30 Changed title

Replies are listed 'Best First'.
Re: Once again looking for Wisdom
by davorg (Chancellor) on Oct 30, 2001 at 15:00 UTC

    Sounds a bit like you're trying to break encapsulation - which is probably a bad thing.

    Given that all access to the values in $self will be via accessor functions (or, at least, they should be) why not let the accessor functions deal with keeping the two values in step.

    sub some_key_from_tn { my $self = shift; if (@_) { # called to set value $self->{some_key_from_tn} = $_[0]; # call Telephone::Number method to set value $self->{tn}->some_key_from_tn($_[0]); } $self->{some_key_from_tn}; }
    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you don't talk about Perl club."

Re: Maintaining Contained Object Attributes
by Fletch (Bishop) on Oct 30, 2001 at 17:02 UTC

    Following up davorg's advice about always going through accesors, you could look into Class::Delegation or Class::Delegate to have those accessors automagically forwarded to be called on contained objects.

(tye)Re: Maintaining Contained Object Attributes
by tye (Sage) on Oct 30, 2001 at 20:22 UTC

    Well, you can use: @{$self}{keys %{$tn}}= \( @{$tn}{keys %{$tn}} ); and then changing ${$self->{some_key_from_tn}} will also change $self->{tn}->{some_key_from_tn}. This can be nice if you have a generic accessor methods (perhaps autoloaded) that could just check if the value is a scalar reference and set/get the referenced scalar in such cases.

    Although the guts of Perl support having two hash values be aliases of each other (AFAICT), the language doesn't provide a way of achieving that (AFAICT). So I suppose you could write some XS code to do what you want.

    So you might be better off doing what davorg suggested. However, even if I went with the accessor route, I'd just have the "fetch" part get the attribute from the contained object rather than keeping two copies in sync.

            - tye (but my friends call me "Tye")