假设我们在代码中有一个块,我们将它分配给一个变量(实例或本地),就像这样。
someName := [ anInstanceVariable doThis. anotherInstanceVariable doThat.]
从外面我想用这种方式:
someName someMessageTheBlockDoesntImplement: argument.
块是否可以对特定选择器someName
执行操作并让anInstanceVariable
或anotherInstanceVariable
执行它并分别返回这些对象?
PS。它可以作为一种各种货运代理。
答案 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 } ]
但你为什么要做那样的事呢?