Re: Storing object references in hashes
- From: "Paul Lalli" <mritty@xxxxxxxxx>
- Date: 31 Jan 2006 05:54:32 -0800
Bryan Balfour wrote:
> Many thanks for getting back.
You're welcome. However, I must ask that you start quoting some
context when posting a reply. Not everyone can or chooses to view
Usenet in a threaded manner, and there is no guarantee that every post
will reach a given newserver in the "right" order, or even at all.
> Thanks to your's and other's posts I now realise that my understanding
> of scoping at the Package level was wrong. I'd assumed that variables
> declared in the main section are 'object level' variables whereas they
> are in fact 'class level' variables. Once I'd realised this my problem
> was obvious. I think you can see that, with this misconception, I
> didn't think the code looked odd
It's been a while since I did any OOP in C++ or similar languages, so
looking back, I guess I can see where you're coming from.
> TRUE/FALSE v's 1/0. Using TRUE/FALSE means more to me than 1/0 so,
> until it's demonstarted to me that it's poor programming, I'll
> continue. I've used this technique for years, together with ON/OFF etc,
> and I'm too old to change now without a good reason.
My only issue with it is that it requires more typing (both by way of
typing TRUE instead of 1, and the declarations of the constants in
every package), for seemingly little benefit.
> Variable scoping at the lowest possible level. Agreed, but I had a few
> problems when I tried to do this as you suggested.
Could you elaborate on what those problems were?
> The best I could do
> is shown in the listing of the current code below. I'd appreciate it if
> you could point out any further improvements. (As way of celebration,
> I've extended the code to list the names sorted on age.)
>
> use warnings;
> use strict;
> use constant TRUE => 1;
> use constant FALSE => 0;
> use Tie::IxHash;
> my(%people, %persons);
> tie %people, "Tie::IxHash"; # Maintain loading order
> %people = (Bryan => 63, Anne => 62, Kevin => 39, Gareth => 35, Siobhan => 31, Kathryn => 28);
> print "Unsorted list...........\n";
> my($person);
Okay. You're declaring one lexical named $person, but using it in two
completely un-related blocks. That is, the last value of $person in
the first block will carry over to the value of $person in the second
block. It is much better to declare two lexicals, one for each block.
(Well, I don't know about "much" better, but certainly "better", IMO)
> while(my($peopleName, $peopleAge) = each(%people))
> {
> $person = Person->new($peopleName, $peopleAge);
my $person = Person->new($peopleName, $peopleAge);
> # Get new instance of Person class and load name and age
> $persons{$peopleName} = $person;
> # New hash entry with name as key and and new object as value
> print "Name: " . $person->getName() . ",\tAge: " . $person->getAge() . "\n";
> }
> print "List sorted on name...........\n";
> my($personsName);
Same here. Lexically scope $personsName each time you need it, unless
you want the values to persist between blocks. (Here, you don't)
> foreach $personsName (sort(keys(%persons)))
for my $personsName (sort keys %persons)
> {
> $person = $persons{$personsName};
my $person = $persons{$personsName};
> # Person object built for this name
> print "Name: " . $person->getName() . ",\tAge: " . $person->getAge()
> . "\n";
> }
> print "List sorted on age...........\n";
> foreach $personsName (sort {$people{$a} cmp $people{$b}} keys %people)
1) lexically declare a new $personsName
2) This sort works only because all your ages happen to be two digits.
Try adding a person of age 5 or age 101, and see what results you get.
You need to tell the sort to compare numerically, not ASCIIbetically:
for my $personName (sort {$people{$a} <=> $people{$b}) keys %people)
> {
> $person = $persons{$personsName};
my $person = $persons{$personsName};
> # Person object built for this name
> print "Name: " . $person->getName() . ",\tAge: " . $person->getAge()
> . "\n";
> }
> exit(TRUE);
>
> package Person;
Remember that if you eventually move the Person package into its own
module (Person.pm), you should enable strict and warnings here, too, as
they will not carry over from the scope of the "main" file.
>
> use constant TRUE => 1;
> use constant FALSE => 0;
>
> sub new
> {
> my($className) = shift(@_);
> my($self) = {name =>$_[0],
> age =>$_[1]};
> bless($self, $className);
> return($self);
> }
>
> sub getName
> {
> my($self) = shift(@_);
> return $self->{name};
> }
>
> sub getAge
> {
> my($self) = shift(@_);
> return $self->{age};
> }
> return(TRUE);
My only other comment is that you seem to be parenthesis-happy. :-)
Keep in mind that 90% of the time in Perl, parens are only needed if
their lack of existance would change precedence or context. Here, from
the line package Person; on down, not a single parentheses pair is
required.
Well, I could try to take issue with the BSD-style of indentation and
bracketing, as opposed to the far-superior K&R style, but I won't.
(No, really, I don't want this flame war! Please, stop! I'm sorry!!
Ahhhhhhh....)
Paul Lalli
.
- Follow-Ups:
- Re: Storing object references in hashes
- From: A. Sinan Unur
- Re: Storing object references in hashes
- References:
- Storing object references in hashes
- From: Bryan Balfour
- Re: Storing object references in hashes
- From: Paul Lalli
- Re: Storing object references in hashes
- From: Bryan Balfour
- Storing object references in hashes
- Prev by Date: Re: How to use Registry functions
- Next by Date: Re: Substitutions in matched patterns?
- Previous by thread: Re: Storing object references in hashes
- Next by thread: Re: Storing object references in hashes
- Index(es):
Relevant Pages
|