在 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 .
所有这些括号都有点口齿不清!但我不能在不关闭每个表达式的情况下使用短路 or:
,因此它的计算结果为布尔值而不是块(或作为 or:or:or:or:< /代码> 消息)。我可以使用二元运算符
|
代替并进行短路,但这似乎不对。
那么处理这个问题的正确 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
通常
or:
的嵌套方式如下:您的嵌套是短路的,但由于对第一个参数的重复测试而效率较低(检查字节码以查看差异)。
您也可以使用在
Object
上定义的assert:
或assert:description:
:Typically the
or:
are nested like this: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:
orassert:description:
that is defined onObject
:每当事情嵌套得如此严重时,就该调用另一个方法了。
一般来说,你的方法应该相对平坦。如果没有,是时候重构了。
Any time things are that heavily nested, it's time to call another method.
In general, your methods should be relatively flat. If not, time to refactor.
您可以简单地用范围内有效的所有点预填充“单元格”字典,即您放置的初始化中的某个位置:
那么在给定点添加单元格的方法将看起来像这样简单:
还有一个辅助方法# Between:和: ,您可以使用它来最大程度地减少代码混乱:
You can simply prefill the 'cells' dictionary with all points which is valid within the range, i.e. somewhere in initialization you put:
then your method for adding a cell at given point will look as simple as:
There's also a helper method #between:and: , which you can use to minimize the code clutter: