我想知道是否可以在Pharo中重写一条消息,以便我的自定义类在检查器/调试器中显示更多描述性信息,就像简单的变量类型一样,例如Integers或Strings。例如:
相反,我希望它显示一个更自定义且内容丰富的描述,包括其内部变量,以便更紧密/更直观地查看变量,而不必单击它并打开另一个图表(因此看不见上图中的信息)。我知道您可以增加下面显示的图表数量,但这不是问题的重点。我想实现以下目标:
我浏览了pharo论坛,但没有发现任何问题,我还尝试覆盖30多种方法,希望其中一种可以更改输出。只有class
消息似乎会更改输出,但是我只能返回Metaclass
的实例,除了弄乱此消息外,还会破坏很多东西。最终,我尝试对调试器进行反向工程,然后使检查器进行查看,以查看在哪一点构造了表,使用了哪些值,或者发送了哪些消息来构建所述值,但这对我来说太过分了,调用堆栈不断增长,并且我什至无法刮擦表面。
幸运的是,在任何Smalltalk中执行此操作都很容易。从对象继承的类型应回答消息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
的好地方,然后从那里进行调试,直到找到罪魁祸首。为此,只需找到最简单的表达式即可重现问题并对其进行调试。在您的情况下,可以在Playground中执行右键单击命令。因此,
(MyPoint on: 14 and: -5) halt
。'a MyPoint'
)。#DoIt
的求值,它回答了结果Object >> #printString
的实现。宾果游戏!现在您可以打开系统浏览器并查看此方法,研究如何在不同的类中实现该方法,等等。您的调查应向您显示最基本的打印信息是#printOn:
。您可能还想看看其他实现者,以便更好地了解人们通常会做什么。 (请记住,写出好#printOn:
是一种极简主义的艺术)
覆盖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:
的发件人,您将看到图像中已经有很多特殊的可视化效果。您可以将其作为如何创建自己的示例,使其完全适合您的需求:)