I'm attempting to solve AoC problem 12 part 2 in Smalltalk. The specific aren't super relevant, but here's the relevant portion of a single-dimensional version of the model I'm using for the problem:
Object subclass: Moon [
| X XX Xin |
init [
X := 0. XX := 0. Xin := 0.
]
Moon class >> new [ | moon | moon := super new. moon init. ^moon]
x: xx [
X := xx. XX := 0. Xin := xx.
]
kinetic [ ^ (XX abs) ]
initialState [ | killmeNow |
killmeNow := ((self kinetic) == 0).
killmeNow := killmeNow and: (Xin == X).
^killmeNow
]
]
moonA := Moon new.
moonA x: 1.
moonA initialState printNl.
As the variable names just might suggest, I'm failing at the highly complex task of checking if a number equals zero and a second number equals a third number. No amount of refactoring of this statement seems to change the ultimate outcome:
Object: true error: did not understand #value
MessageNotUnderstood(Exception)>>signal (ExcHandling.st:254)
True(Object)>>doesNotUnderstand: #value (SysExcept.st:1448)
True>>and: (True.st:116)
Moon>>initialState (omg.st:15)
UndefinedObject>>executeStatements (omg.st:22)
What is the #Value that (self kin == 0) is receiving, why is it not True, and how do I fix this?
The argument of the
and:message must be aBlock(and you are passing aBoolean). Just change your code like thisYou could also have written the same more succinctly as
but, of course, this is secondary. Note that I've used
=instead of==because both have a slightly different semantics and you don't need object identity in these tests (even though==will work as well in your case).For the sake of completeness, let me mention that there is way to and Booleans: the binary message
&does that. So, you could have writtenThe precedence rules of the Smalltalk syntax allow you to remove the parentheses around
self kinetic = 0because here the main message is=which is also binary. The parantheses aroungXin = Xcannot be removed, otherwise&would take precedence over the last occurrence of=.