猴子修补:define_method是否优先于bind?

时间:2018-08-31 19:23:07

标签: ruby

在下面的代码片段中,我用- (void)webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(nonnull void (^)(NSArray<NSURL *> * _Nullable))completionHandler{ NSOpenPanel * openDialog = [NSOpenPanel openPanel]; [openDialog setCanChooseFiles:YES]; [openDialog setCanChooseDirectories:NO]; openDialog.allowsMultipleSelection = NO; [openDialog beginSheetModalForWindow:self.view.window completionHandler:^(NSModalResponse result) { if (result == NSModalResponseOK) { completionHandler([openDialog URLs]); } else { completionHandler(nil); } }]; } 块修补了Foo#bar补丁。初始化define_method的新实例后,我用对父类Foo方法的bind调用覆盖了它,但是当我调用该方法时,由{{1}定义的块}块被调用。为什么bar调用不能改变方法的行为?

define_method

1 个答案:

答案 0 :(得分:7)

您误解了UnboundMethod#bind的工作方式。您调用Module#instance_method以获得UnboundMethod(即没有self的方法):

OriginalFoo.instance_method(:bar)
# #<UnboundMethod: ... >

然后您调用UnboundMethod#bindself附加到该方法,该返回一个Method实例:

m = OriginalFoo.instance_method(:bar).bind(foo_instance)
# => #<Method: ...>

但这不会改变foo_instance中的方法,它所做的就是使self成为foo_instancem.call:{{1 }}对um.bind(obj)没有任何作用,它只是给您obj作为um,而Method作为其obj