Every object should have equal browsing opportunity

Essentially, all objects are created equal. However, in reality, not all of them are treated equally.

Let's consider Pharo. Packages, classes and methods have their own browser. Code history related objects have their own browser. Setting objects have their own browser. Processes have their own browser. A couple of others have such dedicated browsers as well, but that is about it.

The rest of objects (and my current image has some 4.5 million of them) are treated as second rate citizens: the only thing they are offered is a poor basic Inspector. It is true that the Inspector is more than nothing, but it still feels like discrimination.

Why did we get here? Mostly because of the high costs associated to building a browser. The game has changed in the meantime, and as a consequence, we should reconsider our position.

A while ago I announced the Glamorous Inspector as an alternative to the classic Inspector. It uses a metaphor similar to the one of the Moose Finder which, in its turn, is inspired from the Mac Finder:

  • every object gets a pane and has the possibility of spawning another pane for another object to the right, and
  • every object can have multiple presentations through which it can be interacted with.

The responsibility of defining the presentations lies with the object. The definitions are accomplished via extension methods that are marked by means of a pragma. The browser asks each object for methods defining the pragma and builds the presentations from them.

For example, if you get to a Morph object, beside the default list of instance variables, you can also obtain a preview of how it renders based on the following definition:

Morph>>gtInspectorMorphIn: composite
  <gtInspectorPresentationOrder: 90>
  composite morph
    title: 'Morph';
    display: [:each | each imageForm asMorph ]

The method gets as a parameter a Glamour CompositePresentation that can be extended with new presentations. In this case, we show the morph object with a MorphPresentation.

The gtInspectorPresentationOrder: pragma signals the inspector that this presentation should be offered for a morph object. The number argument (90 in our case) is used as a means to order the rendered tabs.

Another way to understand a morph is to browse its children structure. This is defined as:

Morph>>gtInspectorSubmorphsIn: composite
  <gtInspectorPresentationOrder: 80>
  composite tree
    title: 'Submorphs';
    rootsExpanded;
    display: [:each | {each} ];
    icon: [:each |
         | morphForm |
         morphForm := each imageForm.
         (morphForm extent x > 0 and: [morphForm extent y > 0 ])
              ifTrue: [(morphForm scaledToSize: 16@16) asMorph]
              ifFalse: [Form extent: 16@16] ];
    children: [:each | each submorphs];
    when: [:each | each submorphs notEmpty]

This is a slightly more complicated method, but most of the complexity comes from building the icon that should be shown for each of the child morphs. Below you can see a screenshot of inspecting the result of UITheme exampleOtherControls.

Gtinspector-on-morph.png

The Glamorous Inspector relies on a simple and extensible design. You add an extension method with a new presentation and this will appear as a tab in the inspector. This is uniformly applied to all objects.

For instance, Object offers a presentation for handling the object state (i.e., instance variables), and another one for the handling the code of the class of the object (including changing the code). For example, to the left of the picture below you can see the methods associated with the class (in this case it's actually the Morph superclass) of our morph object. Given that the selected method (imageForm) is a unary one, you can simply executed on the spot and open the resulting object to the right. In this case, our object is a Form, and thus, it can also be previewed.

Gtinspector-on-morph-methods.png

The consequence of this design is that you can accommodate several workflows within one integrated Inspector, depending on the context. It also means that you can change the shape of your inspector at runtime. That is, even during analysis, if you need an extra presentation for your current object, you add a little method and you continue your analysis through dedicated interaction.

Every object should be allowed to aspire to its own browser. With Glamour and the Glamorous Inspector, we get a step closer. It is now up to you, especially if you program in Pharo, to listen to your objects and offer them the means to express themselves.


The Glamorous Inspector ships together with the Moose distribution, but it can also be installed separately.

Posted by Tudor Girba at 21 July 2012, 10:34 am with tags assessment, demo, moose, tooling link
|