in reply to Packages, references, & data hiding...

Okay what you are asking is fairly simple once you think about what you want.
What you are doing is something like this:

$buddys = %data;

This is not what you want at all. What you actually want is a scalar which is a reference to %data to be stored in $buddys which you can then dereference in your loop.
This means you want the equivelent of this:

$buddys = \%data;

In _init_Authentication you are already doing half of this ie:

$self->{'buddy_list'} = \%buddylist;

And then in BuddyList, $self->{'buddy_list'} still contains a reference to the hash you want as it does when you try using directly in main. So all you need to return is $self->{'buddy_list'} which then gets put in $buddys and can be used as you wish.

Hope that was what you wanted to know.

Replies are listed 'Best First'.
Re: Re: Packages, references, & data hiding...
by zzspectrez (Hermit) on Dec 04, 2000 at 01:11 UTC

    What I was hoping for, is a way to return the hash of buddys instead of the reference to the hash. Sort of how the Identites method returns the actual array instead of the reference to one.

    Then I could do something like:

    my %buddys = $p->BuddyList; foreach my $key (keys %buddys) { print "GROUP: key\n"; print "NAMES: ", join (' ', @{$buddys{$key}}), "\n"; }

    I guess it is about the same, just take me one step closer to the data and remove the use of one $

    Thanks for the suggestions.
    zzSPECTREz

      It is quicker to return a hash ref, and if you have the hash ref you can still manipulate that hash...just do it like this:

      my $buddys = $p->BuddyList; #this returns a hash ref
      for (keys %{$buddys})
      {
          print "GROUP: $_\n";  #I'm asuming that 'keys' here was a reference to $keys in your foreach...
          print "NAMES: ", join (' ', @{$buddys->{$_}}), "\n";  #similarly, I removed $keys and so I'm using $_
      }
      

      This gives you the speed of using a reference (incedentally, for only a few pieces of punctuation more, you can do the same thing with Indenties and use an arrayref), along with the ease of an actual hash (in the end, that's what it is). you could feasibly get away with

      foreach ( keys %$buddys )
      But I always find it safer to wrap the ref in braces.

      Note that, in general, if foo returns a hashref, you can get the hash (if you *really* need it) by using braces judiciously, e.g.

      my %hash = %{foo(@args_to_foo)}; # or, with a method that returns a hashref my %hash = %{$object->foo};

      Either way, though, you lose some of the speed advantages of passing around references.

      Philosophy can be made out of anything. Or less -- Jerry A. Fodor

      There is one other thing you need to consider between return a hash or hash-ref. Do you want the original data editable?
      Look at this code:
      sub hash { my $h = shift; return %$h; } sub href { my $h = shift; return $h; } my $n = { moo => 'blah', arrg => 'no' }; my %hash = hash($n); $hash{arrg} = 'yes'; print join(' ',%$n) . "\n"; # Output: moo blah arrg no my $m = { moo => 'blah', arrg => 'no' }; my $hash = href($m); $hash->{arrg} = 'yes'; print join(' ',%$m) . "\n"; # Output: moo blah arrg yes
      The first one is what you were doing originally, I don't know why it didn't work. But it is better to return a hash-ref unless you really need to protect the original data (which anyone can get to with $p->{buddys_list} anyway if they really want to).