启动发送未实现消息的代码时,法罗将启动调试器。
据我所知,它通过Object >> doesNotUnderstand工作,这会触发异常,这将导致调试器窗口。

问题是,Object >> doesNotUnderstand到底是做什么的,这与其他交互助手有什么不同,比如从不存在变量开始的交互帮助?
发布于 2019-02-02 20:36:44
调试器是作为对未处理异常的响应打开的。为了更好地解释,我们可以从触发系统中任何地方都没有捕获的异常开始。例如,我们可以在游乐场Error signal: 'an error'.中执行(信号在法老中抛出一个错误)。这将打开以下调试器:

当异常发生时,系统首先尝试为该异常查找异常处理程序。如果没有找到异常处理程序,则系统将消息defaultAction发送到异常。这在类Error中实现为:
Error>>#defaultAction
"No one has handled this error, but now give them a chance to decide how
to debug it. If none handle this either then open debugger
(see UnhandedError-defaultAction)"
UnhandledError signalForException: self因此,系统通过抛出另一个异常UnhandledError来响应未处理的异常。同样,如果没有为新异常找到异常处理程序,则系统将消息defaultAction发送到异常对象。在本例中,异常是UnhandledError的一个实例,该类重写器defaultAction具有以下实现:
UnhandledError>>#defaultAction
<reflective: #unhandledErrorDefaultAction:message:>
^ UIManager default unhandledErrorDefaultAction: self exception方法unhandledErrorDefaultAction:非常简单,只发送异常对象消息debug。
MorphicUIManager>>#unhandledErrorDefaultAction: anException
anException debug方法调试是在Exception中实现的,这是法老中所有异常的根类,如下:
Exception>>#debug
"open a debugger on myself"
Processor activeProcess
debug: self signalerContext
title: self description这就是打开调试器的原因。
在向对象发送未知消息的情况下,MessageNotUnderstood类型的异常将由Object>>#doesNotUnderstand:方法引发。此异常遵循与前面相同的链,系统最终将debug消息发送给打开调试器的MessageNotUnderstood异常。
因此,简而言之:
#doesNotUnderstand:;doesNotUnderstand:引发MessageNotUnderstood类型的异常;UnhandledError的异常;UnhandledError,它会要求UI管理器处理这种情况;debug发送到初始异常,在这种情况下,MessageNotUnderstood异常(只有MorphicUIManager执行此操作;其他UI管理器(如CommandLineUIManager )执行其他操作,如现有图像);debug消息打开调试器。不存在变量的处理程序在实际编译器中有一个完全不同的实现。当代码在具有未知变量的类中编译时,编译器会检测到这一点,并询问用户该做什么:创建一个新的实例变量或一个本地参数。
如果您试图执行包含未知类的代码,比如UnnknowsClass new.,编译器也会检测到这一点,并询问用户该做什么。在这种情况下也没有例外情况。
还有其他帮助程序使用与doesNotUnderstand:相同的机制,例如引发通知。如果执行Object new notify: 'a notification',则notify:方法将抛出一个Warning异常,该异常将最终打开调试器。

发布于 2019-02-03 02:51:52
为了补充Adrei给出的出色答案,让我补充一下,消息#doesNotUnderstad:与其他消息有点不同。
每次发送消息时,运行时(通常在虚拟机中)会找到与所发送消息的选择器对应的方法。
它通过观察接收者的行为来做到这一点。如果找不到任何方法,则会转到继承的行为(通常是超类中定义的方法),然后继续这种方式,直到找到方法或继承链耗尽为止。这种搜索称为方法查找。
在第二种情况下(当在对象的行为层次结构中不存在方法时),Runtime (1)通过创建一个没有找到选择器的Message对象来重新表示消息,而实际的参数(如果有的话)和(2)会向接收方发送一条带有选择器#doesNotUnderstand:的新消息,并对消息进行参数化。
查找过程会重复,而且(很可能)这一次为接收方找到了选择器#doesNotUnderstand: (它可以实现自己的版本,也可以从类层次结构的顶部继承它)。此时,Adrei描述的步骤如下。
如果接收方出于任何原因不理解#doesNotUnderstand: (双关意),则运行时不能继续并关闭系统(它还能做什么?)
还请注意,如果消息被发送到super,则查找会有一点不同。但这是另一个故事和基本思想。这个问题仍然存在。
https://stackoverflow.com/questions/54496857
复制相似问题