【问题标题】:Is it possible to assign a message to a variable?是否可以将消息分配给变量?
【发布时间】:2016-02-12 22:03:59
【问题描述】:

我正在研究不同种类的编程语言,以了解它们有何不同以及它们的优缺点。

我目前对使用消息进行方法调用的语言特别感兴趣;我想知道是否有可能以某种方式将消息分配给 Squeak/Pharo/Smalltalk/etc 中的变量。

假设AB 都有消息foo:;我该怎么做这样的事情:

|msg| 
msg := foo: 12.
a msg.
b msg.

其中ab 分别是AB 的实例

【问题讨论】:

  • 只是为了澄清:您不考虑为此设置块吗?这将是我想到的“转移”消息呼叫的第一种方式。
  • @AmosM.Carpenter 我并没有真正编写 smalltalk,我是从更具教育意义的角度提出这个问题;但请提交块想法作为答案

标签: smalltalk pharo squeak


【解决方案1】:

Pharo 有 Message 类。所以你可以把它创建为

Message selector: #foo: argument: 12

但目前Message 不用于执行目的。

您要查找的是perform: 消息。

所以你可以像这样做你需要的:

| selector arg | 
selector := #foo:.
arg := 12.
a perform: selector with: arg.
b perform: selector with: arg

"for messages of other `shape`"
a perform: selector.
a perform: selector with: arg with: arg. "up to 3 args"
a perform: selector withArguments: { arg . arg }

至于花哨的语法

msg := foo: 12.

根据 Smalltalk 没有任何意义。但是你可以做的是定义一个像GenericMessage 这样的类,它有两个实例变量:selectorarguments。然后你像这样在类端重新定义doesNotUnderstand:

GenericMessage class >> doesNotUnderstand: aMessage

    ^ self new
        selector: aMessage selector;
        arguments: aMessage arguments;
        yourself

那么你还要为Object定义一个方法:

Object>>#performMessage: aGenericMessage

    ^ self
        perform: aGenericMessage selector
        withArguments: aGenericMessage arguments

那么您的代码将如下所示:

|msg| 
msg := GenericMessage foo: 12.
a performMessage: msg.
b performMessage: msg.

【讨论】:

  • 如果消息的形状为foo: 12 withBar: 14,这是否也有效?即有多个论点?还是 Smalltalk 中只有两条消息,而不是 Obj-C 中的一条消息
  • @ElectricCoffee 我添加了更多示例
  • @ElectricCoffee 还添加了一个关于语法的推理,如果你感兴趣的话
  • 我必须在大学里为这个学期设计一门新的编程语言,所以非常感谢添加推理:)
  • 设计一种比 smalltalk 更好的新语言将是一项艰巨的挑战 :)
【解决方案2】:

根据您是只想按名称发送消息还是存储功能以供以后使用,您有不同的选择。在后一种情况下,您可以使用 Smalltalk 的闭包版本 blocks。您将块定义为:

block = [ :arg | arg foo: 12 ]

这意味着每当您使用块 foo: 12 评估 arg 时,都会将其发送到 arg。

您的代码将如下所示:

|block| 
block := [ :arg | arg foo: 12 ].
block value: a.
block value: b

附注我敢打赌你在 Objective-C 中也有同样的东西,它们也被称为块

【讨论】:

  • 是的,但块不只是 lambda experssions?即匿名函数
  • 我认为在 Smalltalk 中:块是闭包,而不是 lambda。
  • @NicoPaez,是的,对不起,他们是关闭的。多亏了你,现在我知道了区别
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-15
相关资源
最近更新 更多