Re: Storing object references in hashes



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

.



Relevant Pages

  • Re: Passing Global Variables, type (date) via DTSRun
    ... You rely on an implicit conversion from date to string - ... when interpreted bh DTRUN or inside the package. ... > DECLARE @CmdStr nvarchar ... >>> several DTS packages that have been created by several developers. ...
    (microsoft.public.sqlserver.dts)
  • Re: file handle
    ... I dont think it should be defined as a signal. ... So you probably want to declare the ... Such procedures can go in a package if you wish. ... DOULOS - Developing Design Know-how ...
    (comp.lang.vhdl)
  • Re: Idiom for a class and an object in Ada
    ... you still have to declare them somewhere. ... declaration in the package body of the package that creates the class? ... > clear to me what you have against access types. ... with things having nothing to do with Ada and I don't see any need to do ...
    (comp.lang.ada)
  • Re: Instantiating private types with discriminants?
    ... I'm still a bit new to Ada terminology - does "making Put a primitive ... Have I got to declare two new packages - one against ... A "primitive operation" of a type T is a subprogram that: ... is declared in the same package specification as T (same declarative ...
    (comp.lang.ada)
  • Re: Hey, Acey!
    ... >> Just to let you know your package went out today. ... I am home sicker than I've been since getting chickenpox at age 21, so>will look for it ... I got the dreaded CP at age 31. ... The time that nearly killed me was when i was about 12 y.o., and consumed some polluted "spring water" in NY State during a camping trip in the Catskills area. ...
    (alt.smokers.cigars)