块内可以知道它收到的选择器并根据它自行评估吗?

时间:2015-09-18 13:56:27

标签: arguments block smalltalk function-composition

假设我们在代码中有一个块,我们将它分配给一个变量(实例或本地),就像这样。

someName := [ anInstanceVariable doThis. anotherInstanceVariable doThat.] 

从外面我想用这种方式:

someName someMessageTheBlockDoesntImplement: argument.

块是否可以对特定选择器someName执行操作并让anInstanceVariableanotherInstanceVariable执行它并分别返回这些对象?

PS。它可以作为一种各种货运代理。

2 个答案:

答案 0 :(得分:4)

这个问题相当令人困惑。首先我想你的意思是“选择器someMessageTheBlockDoesntImplement:”而不是“someName”。但你基本上要求的是能够转发代理。

您通常不使用BlockClosures来实现这一点,而是创建一个继承Object或甚至ProtoObject的MyForwarder类(取决于您使用的Smalltalk以及您希望转发器的透明度)。

在此类中添加两个实例变量,以便您可以保留它们和某些方法,以便设置它们等。

然后在MyForward中实现#doesNotUnderstand:,类似于:

doesNotUnderstand: aMessage
    aMessage selector == #thisMessageGoesToFirstGuy
        ifTrue: [
             ^ firstGuy perform: aMessage selector withArguments: aMessage arguments ] 
        ifFalse: [
             ^ secondGuy perform: aMessage selector withArguments: aMessage arguments ] 

代码未经测试,但您明白了。

答案 1 :(得分:3)

您始终可以通过以下方式实施doesNotUnderstand:课程的BlockClosure

doesNotUnderstand: aMessage
    ^ self value: aMessage selector value: aMessage arguments  

然后你必须有这样一个块:

[ :selector :args |
    ^ { anInstanceVariable      perform: selector withArguments: args.
        anotherInstanceVariable perform: selector withArguments: args } ]

但你为什么要做那样的事呢?