无法在GNU Smalltalk中调用“函数”

时间:2016-04-03 19:52:36

标签: smalltalk gnu-smalltalk

我想定义块并以这种方式调用它:

add := [ :a :b |
    ^(a+b).
].

n := add value: 1 value: 2.

但是当我尝试它时,我收到一个错误:

$ gst 3.1.st 
Object: 3 error: return from a dead method context
SystemExceptions.BadReturn(Exception)>>signal (ExcHandling.st:254)
SystemExceptions.BadReturn class(Exception class)>>signal (ExcHandling.st:151)
SmallInteger(Object)>>badReturnError (Object.st:1389)
UndefinedObject>>executeStatements (3.1.st:3)

如何在GNU Smalltalk中调用函数?

好吧,我删除了return语句,这段代码运行正常。但是当我尝试定义更复杂的函数时,例如:

nod := [ :a :b |
    (a=b) ifTrue: [a].
    (a>b) ifTrue: [nod value: (a-b) value: b].
    (a<b) ifTrue: [nod value: a value: (b-a)].
].

n := nod value: 1 value: 2.
n printNl.

它打印为零。如果我定义为“提前退出”:

nod := [ :a :b |
    (a=b) ifTrue: [^a].
    (a>b) ifTrue: [nod value: (a-b) value: b].
    (a<b) ifTrue: [nod value: a value: (b-a)].
].

n := nod value: 1 value: 2.
n printNl.

它给了我同样的错误:从死方法上下文返回。

我用这种方式解决了这个问题:

nod := [ :a :b |
    (a=b) ifTrue: [
        a
    ] ifFalse: [
        (a>b) ifTrue: [nod value: (a-b) value: b] ifFalse: [nod value: a value: (b-a)].
    ]
].

n := nod value: 1 value: 2.
n printNl.

但我认为,这不是很美好的方式。

3 个答案:

答案 0 :(得分:4)

删除块内的非本地返回(^),括号和句点。并尝试再做一次。

答案 1 :(得分:4)

从代码中删除return语句(^),它将正常工作。

在smalltalk中,返回退出return语句出现的方法。它用于早期退出,例如a < b ifTrue: [^a] ifFalse:[^b]

在这种情况下,您不希望块退出包含方法,只是希望它在发送它时评估为某些内容value:value:。一个块计算它中的最后一个语句,所以只需在那里使它成为一个常规语句,它就可以解决这个问题。

顺便说一下,你得到的错误信息也解释了这个问题:你试图从一个已经死的方法中返回3

答案 2 :(得分:3)

您已经接受了原始问题的答案,然后重新定义了您的问题。

要回答您更新的问题,您可以使用块返回其最后一个语句的值,并使用局部变量:

nod := [ :a :b | |r|
    (a = b) ifTrue: [r := a].
    (a > b) ifTrue: [r := nod value: (a-b) value: b].
    (a < b) ifTrue: [r := nod value: a value: (b-a)].
    r
].
但是,我很好奇,关于背景。我怀疑这可能更适合被定义为类的选择器/方法。

<小时/> 顺便说一句,如果任一参数为负数,则上述实现将进入无限递归。

获得结果的最简单方法是:

nod := [ :a :b | a gcd: b ].

:)