Pharo/Smalltalk中使用的">>"符号是什么意思?

6
我正在Pharo中实现futures。我发现了这个网站:http://onsmalltalk.com/smalltalk-concurrency-playing-with-futures。我在跟随这个例子并试图在Pharo上复制它。然而,当我到达最后一步时,我不知道">>"是什么意思:这个符号也没有作为Smalltalk语法的一部分包含在http://rigaux.org/language-study/syntax-across-languages-per-language/Smalltalk.html中。
BlockClosure>>future
    ^ SFuture new value: self fixTemps

我注意到`future`不是由`BlockClosure`实现的变量或方法。为了使承诺/未来按照http://onsmalltalk.com/smalltalk-concurrency-playing-with-futures中所示的功能工作,您需要怎么做?如果我直接将代码添加到我的Promise类中,就像它现在这样,或者我错过了什么?
在将`future`方法添加到`BlockClosure`之后,这是我尝试在PlayGround上运行的代码。
value1 := [200 timesRepeat:[Transcript show: '.']. 6] future.
value2 := [200 timesRepeat:[Transcript show: '+']. 6] future.
Transcript show: 'other work'.
Transcript show: (value1 + value2).
Date today 

转录显示的是以下错误,而不是预期的值12。
UndefinedObject>>DoIt (value1 is Undeclared) 

UndefinedObject>>DoIt (value2 is Undeclared) 
1个回答

10
由于某种原因,在Smalltalk中有一种传统的符号表示方法,例如在类C中使用选择器m的方法是C>>m。例如,BlockClosure>>future表示具有选择器#future的BlockClosure的方法。有趣的是,这个表达式不是可评估的Smalltalk表达式,也就是说,它不是一个Smalltalk表达式。它只是一种简洁的方式来表示,“下面的内容是类C中选择器为m的方法的源代码”。就是这样。
然而,在Smalltalk中,方法也是对象。事实上,它们是CompiledMethod的实例。这意味着可以通过发送消息来检索它们。在这种情况下,消息是methodAt:。消息的接收者是实现该方法的类,参数是选择器(分别是您的示例中的C和#m,或BlockClosure和#future)。
因此,大多数方言都实现了methodAt:的同义词,称为>>。可以通过以下方式轻松实现这一点:
>> aSymbol
  ^self methodAt: aSymbol

这使得Smalltalk的语法更接近于传统的记法,因为现在 BlockClosure & gt; & gt; future 看起来就像是将消息>>发送到BlockClosure并带有参数future的表达式。然而,除非我们在其前面加上#,否则future不是Symbol类型,即变成#future。因此,如果我们在选择器前面添加#符号,就可以获得文字意义上的Symbol #future,这是一个有效的Smalltalk对象。现在表达式为:
BlockClosure >> #future

这个内容涉及到it技术,它的意思是:一个消息成为了代码块,经过评估后,这个CompiledMethod可以在BlockClosure类的#future选择器中得到。

简单来说,BlockClosure>>future不是有效的Smalltalk表达式,而是一种记号。然而,通过修改它为BlockClosure >> #future,它就成为了一种可以被语言评估的表达式,并返回记号所指的方法。


我将 future 方法添加到 BlockClosure。然而,"^ SFuture new value: self fixTemps" 并不起作用,因为fixTemps消息是“发送但未实现”的状态。我在这个网站https://www.gnu.org/software/smalltalk/manual-base/gst-base.html上查看了一下,关于 fixTemps,它的说法是:fixTemps:-这应该固定块中使用的临时变量的值,这些变量通常与定义块的方法共享。虽未定义,但不构成妨碍。回答接收器。它说“尚未定义”。我如何解决这个问题? - Gakuo
1
@Gakuo 在Pharo中不需要使用fixTemps。只需将self作为参数发送即可。 - Leandro Caniglia
在放弃fixTemps之后,我尝试运行网站上提供的测试代码。但是我遇到了一个错误:“UndefinedObject>>DoIt(value1未声明)”和“UndefinedObject>>DoIt(value2未声明)”。我原本期望这段代码能够像网站http://onsmalltalk.com/smalltalk-concurrency-playing-with-futures上所示的那样工作。 - Gakuo
@Gakuo 变量 value1value2 被定义为 SFuture 的实例,因此如果您评估这些表达式,这些变量将被声明。如果您得到它们未声明的结果,则意味着您尚未评估这些赋值语句。至少,在没有看到您正在做什么的情况下,这是我能想象到的唯一可能性。 - Leandro Caniglia
我相信这一定是其他原因。我每次都逐行执行(ctrl-D),也试图一次性执行整个测试。调试器弹出并且Transcript显示“UndefinedObject>>DoIt(value1 is Undeclared)”和“UndefinedObject>>DoIt(value2 is Undeclared)”,两种情况都是如此。 - Gakuo
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接