Debugging 更改对象在调试器/检查器变量值表中的显示方式

Debugging 更改对象在调试器/检查器变量值表中的显示方式,debugging,smalltalk,pharo,Debugging,Smalltalk,Pharo,我想知道是否有一条消息可以在Pharo中重写,以便我的自定义类在inspector/Debugger中显示更多描述性信息,就像简单的变量类型(如整数或字符串)一样。例如: 与此相反,我希望它显示一个由内部变量组成的更自定义和信息更丰富的描述,以便更紧密/整洁地查看变量,而不必单击它并打开另一个图表(因此忽略上一个图表上的信息)。我知道你可以增加下面显示的图表数量,但这不是问题的重点。我想实现这样的目标: 我浏览了pharo论坛,什么也没找到,我还尝试覆盖了30多个方法,希望其中一个能改变输出

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

与此相反,我希望它显示一个由内部变量组成的更自定义和信息更丰富的描述,以便更紧密/整洁地查看变量,而不必单击它并打开另一个图表(因此忽略上一个图表上的信息)。我知道你可以增加下面显示的图表数量,但这不是问题的重点。我想实现这样的目标:


我浏览了pharo论坛,什么也没找到,我还尝试覆盖了30多个方法,希望其中一个能改变输出。只有
消息似乎改变了输出,但我只能返回
元类
的一个实例,而且弄乱这个消息会破坏很多东西。最后,我尝试对调试器和检查器进行反向工程,以查看表是在哪一点构造的,使用了哪些值,或者发送了哪些消息来构建所述值,但这对我来说太多了,调用堆栈不断增长,我甚至无法触及表面。

幸运的是,在任何闲聊中这样做都很容易。从对象继承的类型应该响应消息
printString
,最终响应消息
printOn:aStream
。这些消息将给出对象的描述。因此,您应该在类中重写
printOn:
printString
使用
printOn:)
,所有浏览器和检查器都将自动使用它。如果您想在不同的选项卡中提供更复杂的信息,在Pharo中还有其他的可能性,但我认为
printOn:
就足够了

例如:

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

在Smalltalk中,每次你观察到你不喜欢或不理解的东西时,你都会问这样一个问题:是哪条信息在这样做?

在您的例子中,问题是:哪条消息创建了我随处可见的字符串
a MyPoint

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

  • 写入并选择
    (MyPoint on:14和:-5)在操场中暂停
  • 右键单击并发出Print it命令(我假设您已经检查过该命令是否生成字符串
    'a MyPoint'
  • 调试
  • 检查
    #DoIt
    的评估,它会回答结果
  • 以这种方式继续,在进入结束之间交替进行,以确保跟踪结果,并将其带到拍摄位置
  • 最终您将实现
    Object>#printString
    。宾果
    现在,您可以打开一个系统浏览器,查看此方法,研究它在不同类中的实现方式,等等。您的调查应该表明,打印最基本的消息是
    #printOn:
    。您可能还想看看其他实现者,以便更好地了解人们通常做什么。(请记住,编写好的
    #printOn:
    s是一门极简艺术)

    覆盖
    printOn:
    将适用于您只想更改描述的简单情况。
    法罗允许的远不止这些
    由于我们inspector的可扩展(可模塑)特性,您无需重写方法即可获得自己的对象可视化效果。
    例如,查看此阵列可视化:

    通过将此方法添加到
    集合中
    ,可以获得:

    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 ]
                        ]
                ]
    
    gtInspectorItemsIn:复合
    ^复合快速列表
    标题:“项目”;
    显示:[self asOrderedCollection];
    多重性;
    格式:[:each | GTObjectPrinter asTruncatedTextFrom:each];
    发送:[:结果|
    结果
    ifNil:[无]
    ifNotNil:[结果大小=1
    ifTrue:[结果任何人]
    ifFalse:[自身物种与所有物种:结果]
    ]
    ]
    
    如果您浏览
    gtInspectorPresentationOrder:
    的发件人,您将看到图像中已经有很多特殊的可视化效果。

    你可以拿这些作为一个例子,说明如何创建自己的,完全适合你需要的:)

    问题:暂停是否等同于断点?因为我创建了一个断点,它打开了十几个窗口,就好像有一些并行在运行,所以我忘了做最后一部分。我确实重写了printString,它改变了print-it的行为,但在检查时没有改变表示。现在我知道,
    printOn
    就是我要找的for@J3STER关于你的问题,其他人应该回答。我不是Pharo用户,所以我不熟悉它对断点的支持。此外,在这方面,这值得提出一个独立的问题。