Thursday, April 14, 2011

Pomodoro scripts

Sous OSX j'utilise ce logiciel comme chronomètre qui a l'avantage de pouvoir exécuter des scripts lorsque le Pomodoro démarre, s'arrête, ....

Au travail on utilise beaucoup la messagerie instantanée. J'utilise Adium comme client.

Besoins:
  • je ne veux pas être dérangé pendant mon Pomodoro (passer mon état à indisponible)
  • je veux que mes collaborateurs sachent quand se termine mon Pomodoro pour me contacter

Solution:

Dans Adium créer un statut indisponible avec comme titre'Pomodoro en cours'



Dans les préférences de Pomodoro, onglet script, configurez comme ceci:


Start:
tell application "Adium" to set the status of every account whose status type is available to the first status whose title is "Pomodoro en cours"


Reset et End:
tell application "Adium" to set the status of every account whose status type is away to the first status whose title is "Disponible"


Every 2 mins:
tell application "Adium" to set status message of every account to "Pomodoro en cours, fin dans $time mn"




Tout le long du Pomodoro votre statut sera mis à jour:



Et dès que quelqu'un ose vous contacter, réponse automatique !

Wednesday, April 13, 2011

Petite Horloge revisited

Another Pharo Smalltalk snippet with temp classes (I like this :)

(Class new
    superclass: StringMorph;
    setFormat: StringMorph format;
    compile: 'step self contents: Time now printString';
    new)
        openInWindowLabeled: 'Petite Horloge'.


Don't forget the setFormat: or the VM will crash.Some explanations.

Polymorph counter example

I've discovered that I can write this in Pharo:

"This creates a class and one instance on the fly"
counter := Class new 
              superclass: Object; 
              addInstVarNamed: 'counter'; 
              compile: 'initialize 
                           counter := 0';
              compile: 'counterString 
                           ^ counter asString';
              compile: 'increment 
                           counter := counter + 1. 
                           self changed:#counterString';
              compile: 'decrement 
                           counter := counter - 1. 
                           self changed:#counterString';
              new.

(UITheme builder newColumn: {
  UITheme builder newLabelFor: counter getLabel: #counterString getEnabled: nil.
  UITheme builder newRow: {
    UITheme builder newButtonFor: counter action: #increment label: '+' help: nil.
    UITheme builder newButtonFor: counter action: #decrement label: '-' help: nil.
  }
}) openInWindowLabeled: 'Counter example'.

Coooooooooooooool ;)

Saturday, March 19, 2011

Multiple worlds for Pharo

Sean DeNigris submitted a changeset to get multiple worlds in Pharo.

I've played a little with it to get a world switcher. If you want it, first file in the changeset file (download it the drag the file on an opened image).

Then the following code add three worlds named 2,3,4 and create a dock in each world.

|wm|
wm := WorldManager instance.
#('2' '3' '4') do: [:aString| wm createOrSwitchToWorldNamed: aString].

wm worlds keysAndValuesDo:  [:aWorldName :aWorld| |dock|
  dock := DockingBarMorph new
          adhereToTop;
          openInWorld: aWorld.

  wm worlds keysAndValuesDo: [:aWorldName2 :aWorld2|
    dock addMorph: (SimpleButtonMorph new
                    label: aWorldName2;
                    target: [wm createOrSwitchToWorldNamed: aWorldName2];
                    actionSelector: #value) ].
                    
  dock addMorph: (StringMorph contents: aWorldName).
].

Monday, February 28, 2011

Work on Mocketry

Mocketry is a Mocketry is Smalltalk mock object framework.

To load it in Pharo:
Gofer it
  squeaksource: 'MetacelloRepository';
  package: 'ConfigurationOfMocketry';
  load.

(Smalltalk at:#ConfigurationOfMocketry) project latestVersion load.


I've done the first part of the Picasa screencast in a TDD way using Mocketry to prevent external HTTP requests.
Gofer it
 squeaksource: 'LaurentLSandbox';
 package: 'Picasa';
 load.

As the requests are done using HTTPSocket class>>httpGet:, one way is to give a mock to PicasaSearch so we can check (and stub) the HTTP request:
PicasaSearchTwoRoughSeaTest>>setUp
  [:mockHTTPSocketClass|
    [photos := PicasaSearch new
        httpSocketClass: mockHTTPSocketClass;
        addKeyword: 'rough';
        addKeyword: 'sea';  
        maxResult: 2;
        photos.] 
 
     should strictly satisfy: [
        (mockHTTPSocketClass httpGet: 
          'http://picasaweb.google.com/data/feed/api/all?q=rough+sea&max-results=2')
        willReturn: self fixtureXMLResponseForTwoRoughSea] 
  ] runScenario.

#fixtureXMLResponseForTwoRoughSea will return an XML string and test methods will check that it is correctly parsed.

In PicasaSearch:
httpGetDocument 
  |url| 
  url := String streamContents: [:aStream|
  aStream 
    nextPutAll: 'http://picasaweb.google.com/data/feed/api/all?q=';
    nextPutAll: ('+'  join: self keywords);
    nextPutAll: '&max-results=';
    nextPutAll: self maxResult asString.    
  ].  

  ^ (self httpSocketClass httpGet: url).


See that mocketry extends BlockClosure to create mocks:
[:myFirstMock :mySecondMock|
"do stuff with mocks"
] runScenario

and set up expectations:
[:myFirstMock :mySecondMock|
  [ "do stuff with mocks" ] 
  should strictly satisfy: 
  [ "what is expected on mocks" ]  
] runScenario

See HelpSystem book loaded with Mocketry for several examples.

Comments and better code propositions are welcome.