Add to a collection
Boris Gaertner
Boris.Gaertner at gmx.net
Mon Feb 3 10:51:42 UTC 2003
Janet Abdul-Karim <jn_karim at yahoo.com> wrote
>
> I created a subclass to ordered collections. I am trying to add objects to the new class and then print it to make sure they are in there. I add one object it prints but when I add another object and print it only prints the first object i added
>
> sample code to add to list.
>
> account: aAccount
> "Add an account to the portfolio"
>
> self isNil ifTrue:[self add: aAccount]
> ifFalse:[ self addLast: aAccount].
>
I think this is an instance method of your subclass. Please note that
self isNil will always return the result false. Perhaps you wanted
to write self isEmpty, which returns true when the collection does
not contain a single element. That test is not necessary, the instance
method addLast: of OrderedCollection works also when the collection
is still empty. Have a lock at OrderedCollection>>add: It calls the
method addLast:, nothing more! So you can simply write
account: anAccount
"Add an account to the portfolio"
self add: anAccount.
It is so very simple, but perhaps you saw difficulties where no
difficulties are? (There are other languages that require the
test for emptiness, you are right.)
>
> code to print list.
>
> ccounts
> "Returns the accounts for the portfolio"
>
> self do:[:element|^element number].
>
>
Here we have a punctuation problem: The small arrow
is a jump instruction. When it is executed the first time, your
method is immediately left with result value element number.
This means that the execution of the do: is terminated after
processing of one single element of the collection.
Ned proposed a better solution. Did you observe that he
did not only replace the do: with collect:, but that he also moved
the arrow to a different place?
In
^self collect: [:element | element number]
the arrow returns the result of the collect expression which in turn is
a collection.
>
>
In a separate mail, you asked for comments about this piece of code:
> findAccount: accountNumber
> "Find the account with the argument number"
>
> self do:[:element | element number == accountNumber
> ifTrue:([Transcript show: element;cr])
> ifFalse:([Transcript show: 'No such account exists in this portfolio';cr])].
Some subscribers already expressed different opinions about the possible
reason of the unexpected result.
I defined two small classes to try your and I see no problem - but there may
be problems in parts of your code that you did not post. You wrote:
>element is an object that has number as a method
Alright. Let us look there. I expect something like:
number
" return the number of the account"
^accountNumber
The arrow is very important, because it says that the
value of instance variable accountNumber is returned.
Without the arrow, the entire instance is returned. Did you
use the arrow?
Additional remarks.
1. The method (without the arrow!)
number
accountNumber.
has the same meaning as
number
accountNumber.
^self
The "^self" causes the receiver instance to be returned.
When you compare the method receiver (an account) with
an account number, you will of course always get the value "false".
2. You wrote:
> ifTrue:([Transcript show: element;cr])
At first sight I was surprised to see this and I was even
more surprised to see it work. A more careful thinking revealed
that it is possible to place the round parentheses around the
block, but they are unnecessary. You may write:
ifTrue: [Transcript show: element;cr]
and this is what you will see in all Smalltalk code.
I hope that our community gives helpful advice, but
please do not hesitate to tell us about advice that does not
help. When your problems persist, we will continue to
think about possible solutions.
With my best wishes,
Boris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20030203/757c43db/attachment.htm
More information about the Squeak-dev
mailing list
|