I'm working on a simple board game in Pharo, and I've got a method on my Board that adds objects to a cell. Cells are simply a dictionary of Points on Objects.
As part of the method, I wanted to enforce that a Point should be greater than zero, but less than the width and height of the board, in other words, it should actually be on the board. What is the best way to do this?
My current attempt looks like this:
at: aPoint put: aCell
((((aPoint x > self numberOfRows)
or: [aPoint x <= 0])
or: [aPoint y > self numberOfColumns ])
or: [aPoint y <= 0])
ifTrue: [ self error:'The point must be inside the grid.' ].
self cells at: aPoint put: aCell .
Kind of lisp-y with all those parens! But I can't use the short-circuiting or: without closing off each expression so it evaluates as a boolean and not a block (or as the or:or:or:or: message). I could use the binary operator | instead and for-go short circuiting, but that doesn't seem right.
So what is the properly Smalltalk-ish way to handle this?
Typically the or: are nested like this:
(aPoint x > self numberOfRows
or: [ aPoint x <= 0
or: [ aPoint y > self numberOfColumns
or: [ aPoint y <= 0 ] ] ])
ifTrue: [ self error: 'The point must be inside the grid.' ].
Your nesting is short-circuting but less efficient because of repeated tests of the first argument (check the bytecode to see the difference).
Alternative you can use assert: or assert:description: that is defined on Object:
self
assert: (aPoint x > self numberOfRows
or: [ aPoint x <= 0
or: [ aPoint y > self numberOfColumns
or: [ aPoint y <= 0 ] ] ])
description: 'The point must be inside the grid.'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With