Reputation: 18242
Can someone explain why this isn't working how I expect?
add: rhsKey
myUnits includesKey: rhsKey
ifTrue: myUnits put: (myUnits at: rhsKey) + 1 at: rhsKey
ifFalse: myUnits add: rhsKey -> 1.
Example execution:
ut := UnitTracker named: 'test'.
ut add: 'seconds'.
ut add: 'seconds'.
ut add: 'seconds'.
ut add: 'minutes'.
It keeps executing through the ifTrue on the first go-round.
Upvotes: 1
Views: 674
Reputation: 9382
Once you grok the keyword syntax, I advise to study/mimic the at:ifAbsent:
message in Dictionary which could be used like this:
myUnits at: rhsKey put: (myUnits at: rhsKey ifAbsent: [0]) + 1
Upvotes: 2
Reputation: 899
ifTrue:ifFalse:
accepts blocks [ ]
as arguments.
If you don't encapsulate the code you want run on true and false in a block it will be executed before the call to ifTrue:ifFalse:
.
You also need to surround myUnits includesKey: rhsKey
in parentheses ( )
, because otherwise the compiler will get confused as to which message you're actually trying to send.
In fact, I'm surprised you didn't get a DoesNotUnderstand exception for that code, as you've effectively sent includesKey:ifTrue:put:at:ifFalse:add:
to myUnits.
With brackets added as you probably intended, it will look like this:
add: rhsKey
(myUnits includesKey: rhsKey)
ifTrue: [ myUnits put: (myUnits at: rhsKey) + 1 at: rhsKey ]
ifFalse: [ myUnits add: rhsKey -> 1. ]
So now ifTrue:ifFalse:
is being sent to the result of myUnits includesKey: rhsKey
Upvotes: 7
Reputation: 16392
Put brackets around the statements in the true and false blocks.
Upvotes: 2