是否可以将消息分配给变量?
Is it possible to assign a message to a variable?
我正在研究不同种类的编程语言以了解它们之间的差异和 advantages/disadvantages。
我目前对使用消息进行方法调用的语言特别感兴趣;我想知道是否有可能以某种方式将消息分配给 Squeak/Pharo/Smalltalk/etc.
中的变量
所以假设 class A
和 B
都有消息 foo:
;我怎样才能做这样的事情:
|msg|
msg := foo: 12.
a msg.
b msg.
其中 a
和 b
分别是 A
和 B
的实例
Pharo 有 Message
class。所以你可以将其创建为
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 没有任何意义。但是你可以做的是用 2 个实例变量定义一个 class,比如 GenericMessage
:selector
和 arguments
。然后像这样在 class 端重新定义 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.
根据您是只想按消息的名称发送消息还是存储功能供以后使用,您有不同的选择。在后一种情况下,您可以使用 blocks,这是 Smalltalk 的闭包版本。您将块定义为:
block = [ :arg | arg foo: 12 ]
这意味着无论何时使用块 foo: 12
评估 arg 都会被发送到 arg。
您的代码将如下所示:
|block|
block := [ :arg | arg foo: 12 ].
block value: a.
block value: b
P.S。我打赌你在 Objective-C 中有同样的东西,它们也被称为块
我正在研究不同种类的编程语言以了解它们之间的差异和 advantages/disadvantages。
我目前对使用消息进行方法调用的语言特别感兴趣;我想知道是否有可能以某种方式将消息分配给 Squeak/Pharo/Smalltalk/etc.
中的变量所以假设 class A
和 B
都有消息 foo:
;我怎样才能做这样的事情:
|msg|
msg := foo: 12.
a msg.
b msg.
其中 a
和 b
分别是 A
和 B
的实例
Pharo 有 Message
class。所以你可以将其创建为
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 没有任何意义。但是你可以做的是用 2 个实例变量定义一个 class,比如 GenericMessage
:selector
和 arguments
。然后像这样在 class 端重新定义 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.
根据您是只想按消息的名称发送消息还是存储功能供以后使用,您有不同的选择。在后一种情况下,您可以使用 blocks,这是 Smalltalk 的闭包版本。您将块定义为:
block = [ :arg | arg foo: 12 ]
这意味着无论何时使用块 foo: 12
评估 arg 都会被发送到 arg。
您的代码将如下所示:
|block|
block := [ :arg | arg foo: 12 ].
block value: a.
block value: b
P.S。我打赌你在 Objective-C 中有同样的东西,它们也被称为块