更改对象在 debugger/inspector 变量值 table 中的显示方式

Change the way an object is displayed in debugger/inspector variable-value table

我想知道是否有我可以在 Pharo 中覆盖的消息,以便我的自定义 类 在 inspector/debuger 中显示更多描述性信息,就像简单变量类型一样,如整数或字符串。例如:

取而代之的是,我希望它显示一个由其内部变量组成的更加自定义和信息丰富的描述,以便获得变量的 tighter/tidier 视图,而不必单击它并打开另一个变量图表(因此看不到上一张图表上的信息)。我知道您可以增加下面显示的图表数量,但这不是问题的重点。我想实现这样的目标:

我浏览了 pharo 论坛但一无所获,我还尝试重写 30 多种方法,希望其中一种方法可以更改输出。只有 class 消息似乎改变了输出,但我只能 return Metaclass 的一个实例,而且除了弄乱这条消息之外还会破坏很多东西。最后,我尝试对调试器进行逆向工程,然后对检查器进行逆向工程,以查看 table 在哪一点构造,使用了哪些值或发送了哪些消息来构建所述值,但这对我来说太多了,调用堆栈不断增长,我什至无法触及表面。

幸运的是,在任何 Smalltalk 中执行此操作都非常容易。从 Object 继承的类型应响应消息 printString,并最终响应 printOn: aStream。这些消息应该给出对象的描述。所以,你应该在你的 class 中覆盖 printOn:printString 使用 printOn:) 并且所有浏览器和检查器都会自动使用它。如果你想要,Pharo 中还有其他可能性在不同的选项卡中提供更复杂的信息,但我认为 printOn: 就足够了。

例如:

MyPoint>>printOn: aStream
    aStream nextPut: ${.
    x printOn: aStream.
    aStream nextPutAll: ', '
    y printOn: aStream.
    aStream nextPut: $}

在 Smalltalk 中,每次您观察到您不喜欢或不理解的内容时,您都会问这样一个问题:哪个消息正在执行此操作?

对于您的情况,问题是:哪个消息创建了我随处可见的字符串 a MyPoint

接下来,要回答您的问题,您需要找到插入 halt 的好位置,然后从那里进行调试,直到找到罪魁祸首。要做到这一点,只需找到能够重现问题的最简单表达式并对其进行调试。在您的情况下,操场上的右键单击命令就可以了。所以,

  1. 游乐场.select(MyPoint on: 14 and: -5) halt中写作和
  2. 右键单击并发出 打印 命令(我假设您已经检查过此命令生成字符串 'a MyPoint')。
  3. 调试
  4. 查看 #DoIt 的评估,它回答了结果
  5. 继续这种方式,在 IntoOver 之间交替进行,以确保您按照结果到达它所处的位置
  6. 最终您将实现 Object >> #printString。宾果!

现在你可以打开一个系统浏览器看看这个方法,研究它是如何在不同的类中实现的,等等。你的调查应该告诉你用于打印的最基本消息是 #printOn:。您可能还想看看其他实施者,以便更好地了解人们通常做什么。 (请记住,写出好的 #printOn:s 是一种极简主义艺术)

覆盖 printOn: 将适用于您只想更改说明的简单情况。
Pharo 允许的远不止于此!
由于我们检查器的可扩展(可塑)性质,您无需重写方法来获得您自己的对象可视化。
例如,看看这个数组可视化:

这是将此方法添加到Collection得到的:

gtInspectorItemsIn: composite
    <gtInspectorPresentationOrder: 0>

    ^ composite fastList
        title: 'Items';
        display: [ self asOrderedCollection ];
        beMultiple;
        format: [ :each | GTObjectPrinter asTruncatedTextFrom: each ];
        send: [ :result | 
            result
                ifNil: [ nil ]
                ifNotNil: [ result size = 1
                        ifTrue: [ result anyOne ]
                        ifFalse: [ self species withAll: result ]
                    ]
            ]

如果您浏览 gtInspectorPresentationOrder: 的发件人,您会看到图像中已经有很多特殊的可视化效果。
您可以将这些作为示例,了解如何创建自己的,完全适应您的需要:)