[英]What is the best way to enforce certain values on message arguments in smalltalk?
我正在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 .
所有那些parens的lisp-y! 但我不能使用短路or:
不關閉每個表達式,因此它評估為布爾值而不是塊(或作為or:or:or:or:
消息)。 我可以使用二元運算符|
相反和前進的短路,但這似乎並不正確。
那么正確的Smalltalk-ish處理這個問題的方法是什么?
通常, 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.' ].
由於第一個參數的重復測試(檢查字節碼以查看差異),您的嵌套是短循環但效率較低。
您可以使用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.'
任何時候都是嚴重嵌套的東西,是時候調用另一種方法了。
isValidPoint: aPoint
aPoint x > self numberOfRows ifTrue: [^ false].
aPoint x <= 0 ifTrue: [^ false].
aPoint y > self numberOfColumns ifTrue: [^ false].
aPoint y <= 0 ifTrue: [^ false].
^ true.
一般來說,您的方法應該相對平坦。 如果沒有,是時候重構了。
您可以簡單地使用在該范圍內有效的所有點預填充“單元格”字典,即在初始化時放置:
1 to: numberOfRows do: [:y |
1 to: numberOfCols do: [:x |
cells at: x@y put: dummy "or nil " ] ]
那么在給定點添加單元格的方法看起來很簡單:
at: aPoint put: aCell
self cells at: aPoint ifAbsent: [ self error: 'The point must be inside the grid.' ].
self cells at: aPoint put: aCell .
還有一個幫助方法#between:和:,您可以使用它來最小化代碼混亂:
((aPoint x between: 1 and: self numCols) and: [
aPoint y between: 1 and: self numRows ]) ifFalse: [ ... bummer ... ]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.