3

私は Pharo で単純なボード ゲームに取り組んでおり、オブジェクトをセルに追加するメソッドをボードに持っています。セルは、オブジェクト上のポイントの単なる辞書です。

メソッドの一部として、Point が 0 よりも大きく、ボードの幅と高さよりも小さい必要があること、つまり、実際にボード上にある必要があることを強制したかったのです。これを行う最善の方法は何ですか?

私の現在の試みは次のようになります。

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 .

それらすべての括弧を使って、一種のLisp-y!しかし、各式を閉じずに短絡を使用することはできないためor:、ブロック (またはor:or:or:or:メッセージ) ではなくブール値として評価されます。代わりに二項演算子を使用して|ショート サーキットを回避することもできますが、それは正しくないようです。

では、これを処理する適切な Smalltalk 風の方法は何でしょうか?

4

3 に答える 3

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.' ].

最初の引数のテストが繰り返されるため、ネスティングは短時間ですが効率が低下します (バイトコードをチェックして違いを確認してください)。

使用できる代替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.'
于 2010-12-10T23:10:13.563 に答える
4

物事が非常にネストされているときはいつでも、別のメソッドを呼び出すときです。

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.

一般に、メソッドは比較的フラットである必要があります。そうでない場合は、リファクタリングの時間です。

于 2010-12-11T22:23:29.170 に答える
3

「セル」辞書に、範囲内で有効なすべてのポイントを事前に入力するだけです。つまり、初期化のどこかに入れます。

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:and: もあります。

((aPoint x between: 1 and: self numCols) and: [
 aPoint y between: 1 and: self numRows ]) ifFalse: [ ... bummer ... ]
于 2010-12-11T00:02:42.917 に答える