Monthly Archives: March 2016

CDB implementation

Hi guys

just a little announce. Four students in our lecture released a Pharo implementation for CDB .
We published a configuration in the Pharo40 Catalog
Code is here:

location: ‘’
user: ”
password: ”


Pharo FogBugz In Pharo


played with the JSON API of Pharo FogBugz issue tracker with the outcome of 
another little Pharo tool that lets you:

 - login to FogBugz from Pharo
 - enter a string and search for according issues
 - open a browser on a selected issue in the result list (works on Linux and Win so far)

The project repo is at:!/~TorstenBergmann/FogBugz

One can use the client also directly:

client := FogBugzClient loginUser: '' password: 'secret'.
(client query: 'UFFI') inspect.
client logout

You can download the tool in latest Pharo 5 (50660 or later) from catalog
or by opening the Spotter and entering "FogBugz", wait and hitting ENTER.

Attached is a screenshot.


New Version of Ghost: the proxy library

I finished new version of Ghost:
  • DNU approach for basic proxies instead of #cannotInterpret: trick (trick used only for class proxies)
  • Abstract proxy classes uses Ghost name instead of Proxy: there are GHObjectGhost and GHClassGhost.
  • GHProxyHandler renamed to GHGhostBehaviour. Concrete ghosts should implement #ghostBehaviour instead of #proxyHandler.
  • GHGhostBehaviour should define #currentMetaLevel to specify set of messages which should not be intercepted. Such meta messages will be executed under ghost instance by subclass of GHMetaMessages.
In previous version there was dictionary which maps meta message selector to implementation selector. It was not suitable. Now meta messages should be directly implemented on particular GHMetaMessages subclass and all it methods are considered meta.
So GhostBehaviour should return instance of GHMetaLevel with meta messages implementation class:
    • GHMetaLevel with: GHEmptyMetaMessages “when all possible messages should intercepted”
    • GHMetaLevel with: GHStandartMetaMessages “when tools specific messages should not be intercepted”
For example standard meta messages implements #inspect:
“Create and schedule an Inspector in which the user can examine the receiver’s variables.”
^ Smalltalk tools inspector inspect: ghost
  • Traits for methods explicitly defined on ghosts: TMinimalProxy, TNotNilProxy, TIdentifiedProxy (with #=, #hash, #class). Concrete proxies can add this traits to itself independently from meta level. For example traits supply convenient methods to retrieve ghost information in polymorphic way with objects:
    • ghost isGhost
    • ghost ghostClass “returns actual class of receiver”
    • ghost ghostPrintString “returns string which represents ghost from meta level point of view”
This traits are suitable and they provide some kind of optimisation for proxies (methods from traits are executed directly instead of complex meta messages mechanizm). But maybe they are superfluous. For example they can’t be reused for class proxies which substitute real object classes (to intercept all instance messages).
  • GHClassGhost able to replace class of real objects. It implements cannotInterpret: trick to intercept all instance messages. Subclasses should define two behaviours: #ghostBehaviour (as any other ghost) and #instancesBehaviour which will process instance messages. In previous version it was different message to same #ghostBehaviour.
  • New kind of proxies:
    • GHObjectVirus. It is special kind of GHClassProxy. It infects real object to intercept it messages. From meta level infected object looks like healthy object which means that meta messages are executed by infected object itself. As class virus looks like real victim class. So in case when virus is created with standard meta level tools will not differ him from health object. There are special messages which allow ask object about viruses:
      • infectedObject isInfectedByVirus
      • infectedObject virus
      • infectedObject recoverFromVirus
    • GHLearningObject. It is suitable proxy which retrieves all unknown methods from teacher class. Thank’s Stephan for this idea.
This kind of proxy allows me easily find required set of messages to support inspectors and debuggers. You can create instance of learning object by:
GHLearningObject withTeacher: Object.
And any operation with it will fill studiedMessages dictionary. In my case I opened GTInspector on it and got all messages which was needed for him.
  • Ghosts works correctly with latest Pharo 5 tools (basic inspector, GTInspector, SpecDebugger, GTDebugger). Required methods for tools are extracted to ‘Ghost-GTSupport’ package.
  • Repackaging:
    • Ghost-ObjectProxies. It contains all core classes and abstract GHObjectGhost which is based on DNU
    • Ghost-ClassProxies. It contains code for proxy which can substitute class of real object. GHClassGhost implements cannotInterpret: trick to intercept all instance messages. And it implement support for debugging such methods.
    • Ghost-LearningObject
    • Ghost-ObjectVirus
    • Ghost-GTSupport
    • test packages
  • All code moved to Pharo repository!/~Pharo/Ghost (in includes packages from CAR repo too)
You can load new version by:
Gofer it
smalltalkhubUser: ‘Pharo’ project: ‘Ghost’;
configurationOf: ‘Ghost’;
I use it now in Seamless and Mocketry.

Seaside for Pharo50 call for early users

Hi Pharoers,

If you are looking to use Seaside in Pharo 5, please go ahead and let us know if you run into any issues.
Seaside 3.1.5 and 3.2.0 (unreleased) load into Pharo 5 and all tests are green [1].
Also: I know the finalization of 3.2.0 is long overdue, so news about that is coming soon.
“Load release 3.1″
Metacello new
    configuration: ‘Seaside3’;
    version: #’release3.1′;
“Load pre-release 3.2″
Metacello new
    configuration: ‘Seaside3’;
    version: #’3.2.0′;

Preparing PharoLauncher for the classroom


I was asked on #slack by user embee (Martin Baehr) how he can create an up to date setup with "PharoLauncher" 
configuration locally that he can afterwards easily distribute ("unzip and go") to 40 Windows PCs for a 

He was preparing Pharo for Singapore FOSSASIA conference workshop at the science center computer lab.

I helped him with the following short guide that may be useful to others too.

Have fun


A. Portable version of Launcher vor Windows
  1. Go to and click on "VERSION=stable"
     for a green build  
  2. Download ""
     (Direct link is,VERSION=stable,VM=vm,label=linux/lastSuccessfulBuild/artifact/

  3. Extract this to c:\ so you end up with a directory "c:\Pharo"

B. Create some folders
  4. Create a new folder "images" 

  5. Create a new folder "vm" with two subfolders "spur" and "nonspur"
So you end up with  
  - Pharo 
  !- images
  !- vm
   !- spur
   !- nonspur

C. Install stable "non-Spur" VM
The existing stable VM (before the introduction of Spur) is required for all "PreSpur" images with image version <= 50496
(so latest Pharo 4 and initial images when Pharo 5 was started before switching to Spur during Pharo 5 development)
  6. Visit and download ""
  7. This is the Pharo 4 stable Cog VM. Extract the contents to "C:\Pharo\vm\nonspur"

  8. Copy the source files
           C:\Pharo\PharoV10.sources also to C:\Pharo\vm\nonspur
		   C:\Pharo\PharoV20.sources also to C:\Pharo\vm\nonspur
		   C:\Pharo\PharoV30.sources also to C:\Pharo\vm\nonspur
		   C:\Pharo\PharoV40.sources also to C:\Pharo\vm\nonspur  
D. Install latest Spur VM 
The new, fast and shiny Spur VM is required for all "Spur" images with image version 50497 onwards
(so latest Pharo 5)

  9. Visit and download ""   
 10. This is the "bleeding edge" Spur VM. Extract the contents to "C:\Pharo\vm\spur"
 11. Copy only the source file
           C:\Pharo\PharoV40.sources also to C:\Pharo\vm\spur

E. Configure Pharo Launcher
 11. Start C:\Pharo\Pharo.exe by double clicking on it, this will open the Pharo Launcher window
 12. At the bottom right corner of the Window there is a button called "Open Settings". This opens 
     the settings browser for Pharo Launcher. Click on the node "PharoLauncher" in the settings tree.

 13. For the setting "Spur VM Full Path" enter ".\vm\spur\Pharo.exe" and hit ENTER
 14. For the setting "VM Full Path" enter ".\vm\nonspur\Pharo.exe" and hit ENTER
F. Hack the "images" folder location to be relative
 15. When you try to change "Location of your images" to be relative like ".\images" you will 
     notice that it always changes back to an absolute path "C:\Pharo\images". So we need to hack
 16. Hit "SHIFT" + "ENTER" to open the Pharo Spotter. Enter "PhLDirectoryBasedImageRepository" 
     to open a browser on this class. and change the class method #location to look like
	       ^ FileSystem workingDirectory / 'images' 
 17. Close the class browser, close the settings browser and leave the Pharo Launcher by
     clicking on "Quit" in the bottom right corner. Note that the launcher image is saved
	 on exit - so our code change will be in effect when we start Launcher again.
Now ZIP the c:\Pharo folder and you can extract it on any computer that you like.

So when you distribute the ZIP the image folder should be clean. But you can also download
and include preconfigured images that you like your audience to be working with.
G. Sharing caches
With the above setup each time you download and start an image using the Launcher a new
"package-cache" for Monticello/Metacello downloads will be created for each image directory.

To avoid such a cache per image and use a general cache for all images it is helpful to
change the package-cache location in each image. This can easily be done:

  18. Start an image and evaluate 
        StartupPreferencesLoader preferencesGeneralFolder
	  to find out which preferences folder usually is used. In my example this is 

  19. Go to this folder and create a file called "" with the following contents:
        mczCache := 'C:\Software\Pharo\cache' asFileReference.
        MCCacheRepository cacheDirectory: mczCache.
        UIManager inform: 'Package cache set to', mczCache fullName

If you solely work with the setup and following our path logic you can even give this as 
a relative path in the startup script:
        mczCache := FileSystem workingDirectory parent parent / 'package-cache'
Details on further startup customization can be found on		

Another batch of enhancements

17801 EditingState/RubEditingState >>#addUndoRecord: sends a unimplemented message

17534 Transcript does not work after image save and restart

16274 Text-Core should not depend on Tool-Base

17820 QualityAssistant v2.5.1

17811 { film . FILM } is formatted as { film . FILM . }

17807 WorldMorph settings should be able to set both background image and color from the settings

17793 Get coherent diff for metacello packages
17791 RPackage-Core extends Monticello

17794 MCStWriter should be able to do not write initializers

17809 Can not create a subclass of TestCase

17788 Clean old startup mechanism – part 5

17806 Make Metacello rules optional in Versionner

17816 SystemSettings should be last in the startupList of SessionManager

17813 TransformationMorph rightClick behavior is broken
17800 load UnifiedFFI 0.15
17182 Unify adding slots and correct initialization of class slots

17717 Clean old startup mechanism – part 4
16537 FTDataSource>>elementAt: should not be there.

16330 Text*Link users should use RubText*Link

17774 Use isIntegerPoint instead of “x isInteger and: [ y isInteger ]” in some Point methods

17773 CircleMorph should use default initialize methods instead of #initialize

16368 refersToLiteral: should (for now) just call hasLiteralThorough:

17768 remove again isEphemeronClass and isImmediateClass

17766 StandardSystemFontsTest is either unfinised or obsolete

17736 Growl raise debugger instead of a popup at startup

17758 Rectangle>>#areasOutside: inconsistent return value

17752 Point>>#asFloatPoint and Point>>#asIntegerPoint should not create new instances all the time. Add Point>>#isFloatPoint

17761 move #astNodes messages to the Reflectivity package

17763 RingChunkImporter>>#msgClassComment:with: still uses Text for class comments

17747 Nautilus history navigation hotkeys prevent entering square brackets on german/spanish Mac OS X

17764 Update UFFI
17745 RBParser>>parseLiteralByteArrayObject doesnt consume token on error

17762 move DisplayScreen related DummyUIManager messages to the Graphics-Display Objects package

17760 QualityAssistant v2.4.0
13376 Wrong TextMorph extent for ButtonMorphs

15733 let MessageTally ignore #home and just use #sender to handle block closures correctly

15562 rewrite tests that are skipped when old compiler is unloaded

17746 adding a Slot to an anonymous class sets name ivar.

17739 remove duplicated methods from Traits

17392 FreeType numCharMaps nil causes Array>>basicNew: to fail

17740 RBSelfSentNotImplementedRule needs to ignore Traits methods

17215 Proposed fix for OCLiteralVariable>>emitValue:

17132 better comment for flushcache
16422 BlueInk Formatter breaks line even with enough space

17197 CheckBoxModel & RadioButtonModel desactivated* => deactivated*

17733 add support for enums and valueholders
17655 Changes in package loading behavior

17692 ProfStef does not correctly use code font
17716 Clean old startup mechanism – part 3

17698 Debugger step through proxies is not always working

17727 failing test: testWorkspaceIsNotAValidContext

17721 Starting Image 50617 raises MNU
17704 Failing test on CI for mac: KMCombinationTests>>#testMacMetaShouldBeCmd

17713 select right fallback UIManager

17686 Add rules about Rubric method precedence
17711 Reset Registry of MetacelloProjectRegistration to remove Obsolete configuration instances

17712 clean old startup mechanism – part 1

17655 Changes in package loading behavior
17706 deprecate #implementorsExistOf:…

17700 add stub NB classes to easy migrations
17686 Add rules about Rubric method precedence

17689 BoxedFloat Fix remaining Tests

17685 Add rules to check if Float system classes are referenced

Monthly Newsletter Feb 2016

Pharo Monthly Newsletter Feb 2016

We will start our monthly email to keep you in touch with the Pharo world.
You receive this mail because you subscribed at some point at
In case of a mistake: there is link at the end of the mail to unsubscribe.Many things are happening as usual, far too many to list in one email.

The plan is to send one mail per month, never more, with just a selection of
all the things happening. (This one is late, it was for Feb 2016… there will
therefore be one more end of March)

If you are interested in all the news, there are blogs and twitter accounts to
follow. For example:

For a complete list, see

Pharo 50 beta is getting well on track. We expect to have a release in Mid-April. We now have:

  •  Spur the new memory manager developed by Eliot Miranda.Spur includes new GC, new object representation, support for ephemerons, pinned objects and a lot more.
  •  new uFFI compatible with latest Spur memory manager.
  • new version of GT toolkit tools.
  • … and many great enhancements (break point, browser improvements,…)

To play with Pharo5, the latest development snapshot is available at

PharoDays 2016: Two days at Namur to talk and exchange ideas about Pharo, see

More manpower: Pavel Krivanek, the creator of the Pharo mini image shrink, has joined on a one-year position to work on the bootsrap and other projects.

The Pharo consortium is growing, we are preparing an announcement for later this month.

One Page Browser

| classToView browser list nav |
classToView := TextMorphForFieldView.
nav := SystemNavigation new 
			browsedEnvironment: RBBrowserEnvironment new;
browser := MessageBrowser new
	title: 'aTitle'; 
	autoSelect: classToView name; 
	messages: #();
list := FTEasyListMorph new
	hResizing: #spaceFill; 
	vResizing: #spaceFill;
	elements: (classToView  withAllSuperclasses reversed flatCollect: [ :cls | cls instVarNames ]);

list onAnnouncement: FTSelectionChanged do: [ :ann | | ivar |
	ivar := [ list dataSource elementAt: ann newSelectedRowIndexes anyOne ] ifError: [ nil ].
	ivar ifNotNil: [ browser messages: (nav allAccessesTo: ivar from: classToView ) ]].

(AlignmentMorph new
	addMorph: browser buildWithSpec;
	addMorph: list;
	openInWindowLabeled: 'Stuff')
	position: 20@20;
	extent: 900@620.

And you get!

Screen Shot 2016-03-09 at 22.07.56.png

SelectEntity, a new widget for Spec

When using data entry applications,
we often have to select one entity out of a large list.
Spec provides the entryCompletion option for text fields for that.
That works well for small lists
When the number of different entities grows large however,
or when we want to be able to add a new entity,
the traditional solution is to combine an entry completion field
with a button that opens a dialog. This is what SelectEntity provides.
In addition, it supports limiting the choices shown based on
the context in which the field is shown.

I’ve created a small demo application that can be found on smalltalkhub:

Gofer it
smalltalkhubUser: ‘StephanEggermont’
package: ‘Ancestry’;

It can be started with:

ANPersonList new openWithSpec.


Thanks to Peter Uhnak for the design comments & debugging