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
答案 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
这样的类,它有两个实例变量:selector
和arguments
。然后你在课堂上重新定义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中有同样的东西,它们也被称为块