在smalltalk中覆盖'+',接受两个参数?

时间:2013-06-12 00:33:11

标签: smalltalk

是否可以覆盖smalltalk中的+运算符以接受两个参数?即,我还需要传递我的自定义类的单位。类似的东西:

Number subclass: #NumberWithUnits
instanceVariableNames: 'myName unitTracker'
classVariableNames: ''
poolDictionaries: ''
category: 'hw3'


+ aNumber theUnits
    unitTracker adjustUnits: theUnits.
    ^super + aNumber

或者有没有更简单的方法可以做到这一点,我没有考虑过?


其他问题说明:

  

(NumberWithUnits值:3个单位:#seconds)应该为您提供代表3秒的 NumberWithUnits 。但是你也应该写3秒,并且应该评估为 NumberWithUnits (已经在Pharo 2.0中采用了几秒)。执行此操作的方法是向Number添加sec方法,该方法基本上返回(NumberWithUnits值:self unit:#seconds)。您也可以添加米和大象的方法。然后你可以写一个表达 3 elephants /(1 sec sec),它会返回正确的东西。为它写一个测试,以确保它!

2 个答案:

答案 0 :(得分:5)

您缺少的是Smalltalk中的评估/优先顺序。它实际上比大多数其他语言简单得多:

  1. 明确的括号()
  2. 一元
  3. 二进制
  4. 关键字
  5. 任务:=
  6. 因此,您可以在Number上实现一元方法,该方法在二进制+之前进行评估。一个简单的例子是Number>>negated,这是Smalltalk版本的一元减号。

    至少在Squeak / Pharo(我现在所有人都很方便)中,日期算术已经类似地实现了。例如,请查看Number>>minutes,以便评估5 hours - 3 minutes之类的内容,这些内容会返回Duration 0:04:57:00

答案 1 :(得分:4)

我认为更为惯用的方法是构建第二个NumberWithUnits,然后添加它。

然后在你的+方法中,你需要协调所添加的两件事的单位,然后加上它们的大小。

类似

a := Measure new: 2 #m
b := Measure new: 10 #mm

a + b

Measure class [

    + other [
        "TODO: check/convert units here"
        resultMagnitude := (a magnitude) + (b magnitude).
        combinedUnits := (a units) * (b units).
        ^Measure new resultMagnitude units: combinedUnits.
    ]

]

另请参阅示例the GNU Smalltalk example of operator overloading