Add to a collection

Boris Gaertner Boris.Gaertner at
Mon Feb 3 10:51:42 UTC 2003

Janet Abdul-Karim <jn_karim at> 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?
    ^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:

   " return the number of the account"

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!)


has the same meaning as


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,

-------------- next part --------------
An HTML attachment was scrubbed...

More information about the Squeak-dev mailing list