Is it possible to assign a message to a variable?

时间:2016-02-12 22:03:59

标签: smalltalk pharo squeak

I'm studying different kinds of programming languages to see how they differ and their advantages/disadvantages.

I'm currently particularly interested in languages that use messages for method calls; and I was wondering if it's possible to somehow assign a message to a variable in Squeak/Pharo/Smalltalk/etc.

So let's say both class #include <iostream> using namespace std; main() { cout << "Hello World!\n"; return 0; } and A have the message B; how can I then do something like this:

foo:

Where |msg| msg := foo: 12. a msg. b msg. and a are instances of b and A respectively

2 个答案:

答案 0 :(得分:3)

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.

答案 1 :(得分:1)

根据您是否只想通过它发送消息的名称或商店功能供以后使用,您有不同的选择。在后一种情况下,您可以使用 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中有同样的东西,它们也被称为块