Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to enforce certain values on message arguments in smalltalk?

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?

like image 246
CodexArcanum Avatar asked Nov 25 '25 07:11

CodexArcanum


1 Answers

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.'
like image 112
Lukas Renggli Avatar answered Nov 28 '25 15:11

Lukas Renggli



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!