簡體   English   中英

在smalltalk中對消息參數強制執行某些值的最佳方法是什么?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM