Tutorial: Hello world
May 29, 2026 ยท View on GitHub
This tutorial will guide you in the creation of your first Launchpad-based application: The classic hello world!
Preparation
To start, you will need a Pharo image with Launchpad loaded. Follow the instructions to load Launchpad in Pharo.
This tutorial assumes some familiarity with Pharo. If it is your first time using Pharo, you can start with the Pharo documentation.
Minimal command-line knowledge is a plus.
Lesson 1, greeting the world
In this first lesson, we will create an application outputting Hello world!
to the standard output.
Let's start by opening our Pharo image and then the System browser. Now
we're going to create a package to host the code we will produce in the tutorial.
Open the contextual menu in the package list and click on New package. Use
Launchpad-Tutorial as the package name.
Create a new class with the following definition:
LaunchpadApplication subclass: #LaunchpadHelloWorld
instanceVariableNames: ''
classVariableNames: ''
package: 'Launchpad-Tutorial'
Now we need to define a few methods for the class to work. Start with the class side ones, switch to Class side and implement:
commandName
^ 'hello-world'
configurationParameters
^ #()
description
^ 'Hello world'
version
^ '1.0.0'
Switch to Inst. side in the browser and implement:
stackTraceDumper
^ NullStackTraceDumper new
basicStartWithin: context
context outputStreamDo: [ :out |
out
nextPutAll: 'Hello world!';
cr ].
self exitSuccess
Now we are ready to test it!
-
Save your Pharo image and quit the UI.
-
Open a console placed in the image location and type:
pharo Pharo.image launchpad listIf everything is ok, you must be seeing a list including
hello-world -
Now try it for real, type:
pharo Pharo.image launchpad start hello-worldThe output must look similar to:
2021-11-18T17:29:11-03:00 [INFO] Obtaining configuration... 2021-11-18T17:29:11-03:00 [INFO] Obtaining configuration... [DONE] Hello world! -
Great! Try one more thing before going into the analysis of what we learned. Now type:
pharo Pharo.image launchpad explain hello-world
Let's recap what we learned. I will ignore configurationParameters and
stackTraceDumper for now.
- To reference the application in the command-line, use the name declared in
commandNamemethod - The help system uses
descriptionandversionmethods - The real work starts in
basicStartWithin:. In our case, we accessedstdoutthrough the provided context to writeHello world!and then exited the application successfully.
Lesson 2, the world is not enough
Now we're going to make a tiny change. Instead of always greeting the world, we want the option to greet an alien. The user running the application will provide the alien's name.
Reopen the Pharo UI with the image of the previous lesson and change the following methods:
configurationParameters
^ { OptionalConfigurationParameter
named: 'Alien name'
describedBy: 'The name of the alien or people to greet'
defaultingTo: 'world' }
basicStartWithin: context
context outputStreamDo: [ :out |
out
nextPutAll: 'Hello';
space;
nextPutAll: self configuration alienName;
nextPutAll: '!';
cr ].
self exitSuccess
-
We will use again the
explaincommandpharo Pharo.image launchpad explain hello-worldthe output is slightly different now.
-
Since we added an optional parameter, we can continue starting the application as before getting the same output (but more logging info):
pharo Pharo.image launchpad start hello-world -
At last, try it with a parameter
pharo Pharo.image launchpad start hello-world --alien-name=protthe expected output must be
2021-11-18T17:56:24-03:00 [INFO] Obtaining configuration... 2021-11-18T17:56:24-03:00 [INFO] Alien name: prot 2021-11-18T17:56:24-03:00 [INFO] Obtaining configuration... [DONE] Hello prot!
Let's recap this second lesson:
- We introduced an external configuration parameter. In the example, we provide it using command-line arguments. But there's support for environment variables or configuration files (review the reference for more details).
- We changed the startup code to access this configuration parameter and use it to
produce the desired output. If you noticed it, there was a bit of magic accessing
the configuration because we didn't define
alienName. Launchpad infers the method name from the configuration parameter name.
Lesson 3, the formal presentation
Our users requested a last-minute change. We now need to provide a mandatory message to be given with the greetings. This message is confidential information, so it only needs to appear in the greetings.
Reopen the Pharo UI with the image of the previous lesson and change the following methods:
configurationParameters
^ {
(OptionalConfigurationParameter
named: 'Alien name'
describedBy: 'The name of the alien or people to greet'
defaultingTo: 'world').
(MandatoryConfigurationParameter
named: 'Message'
describedBy: 'The message to report'
convertingWith: #asUppercase) asSensitive }
basicStartWithin: context
context outputStreamDo: [ :out |
out
nextPutAll: 'Hello';
space;
nextPutAll: self configuration alienName;
nextPutAll: '!';
cr.
out
cr;
nextPutAll: self configuration message;
cr ].
self exitSuccess
-
First, we will try again the
explaincommandpharo Pharo.image launchpad explain hello-worldthe output is slightly different now.
-
Since we added a mandatory parameter if we start the application as before, we will get an error:
$ pharo Pharo.image launchpad start hello-world [INFO] Obtaining configuration... [WARNING] "Alien name" parameter not provided. Using default. [ERROR] "Message" parameter not provided. You must provide one. -
Now we try a correct invocation:
pharo Pharo.image launchpad start hello-world \ --alien-name=Spock --message="Live long and prosper"the expected output must be
2021-11-19T10:40:41-03:00 [INFO] Obtaining configuration... 2021-11-19T10:40:41-03:00 [INFO] Alien name: Spock 2021-11-19T10:40:41-03:00 [INFO] Message: ********** 2021-11-19T10:40:41-03:00 [INFO] Obtaining configuration... [DONE] Hello Spock! LIVE LONG AND PROSPER
Let's recap this lesson:
- We introduced a new kind of parameter, a mandatory one. When one of these parameters is missing, Launchpad reports an error and exits with an error code.
- We also introduced the
asSensitivemessage, whose purpose is to avoid leaking parameter values in the logs. - To create the parameter, we used an instance creation method with a converter. Optional parameters also have support for them. Converters transform the parameter values before storing them in the configuration. Any object responding to cull:/value: can be used as a converter.