在smalltalk中对消息参数强制执行某些值的最佳方法是什么?

Cod*_*num 3 smalltalk pharo

我正在Pharo做一个简单的棋盘游戏,我在我的棋盘上有一个方法可以在一个单元格中添加对象.单元格只是对象上的点的字典.

作为该方法的一部分,我想强制一个Point应该大于零,但小于板的宽度和高度,换句话说,它应该实际上在板上.做这个的最好方式是什么?

我目前的尝试看起来像这样:

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 .
Run Code Online (Sandbox Code Playgroud)

所有那些parens的lisp-y!但是我不能在or:没有关闭每个表达式的情况下使用短路,因此它评估为布尔值而不是块(或作为or:or:or:or:消息).我可以使用二元运算符|代替和for-go短路,但这似乎不对.

那么正确的Smalltalk-ish处理这个问题的方法是什么?

Luk*_*gli 6

通常or:嵌套如下:

(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.' ].
Run Code Online (Sandbox Code Playgroud)

由于第一个参数的重复测试(检查字节码以查看差异),您的嵌套是短循环但效率较低.

您可以使用的替代方案assert:assert:description:定义于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.'
Run Code Online (Sandbox Code Playgroud)