'Smalltalk (Pharo) How to interface with the user simply
I stumbled upon Smalltalk and further downloaded Pharo, because it was recommended. My first impression is very positive. I wanted to port some simple programs I have written in C++ (my main language), so I can get a feel for Smalltalk.
However, I realized I can't find a simple way to just get some input from the user, e.g. I want to create a console calculator with a REPL loop, but I can't find a way to do this in Pharo. I don't want a gui with buttons, because that is just slow and inconvenient.
Could someone please point out to me how to do simple stuff in Smalltalk, like have the user enter 10 numbers or a command etc.? Do I have to use a different implementation? I'm aiming at std::cin/cout or python's print/input
I know Transcript show:, but that only covers the output portion.
Thanks in advance!
Solution 1:[1]
Getting input from the user is easy, but emulating a line-based console not so much. At least it would be more cumbersome than relying on the GUI, which is not really so slow and inconvenient after all.
The closest input equivalent to Transcript show:
would be:
UIManager default request: 'Title of the request'
If you mark this snippet and "print it" or "inspect it", you will see a prompt dialog and can type something into it. When you accept the dialog with OK or return, you will get the entered String back as the return value of request:
.
Getting ten numbers could be done like this:
(1 to: 10) collect: [:each | (UIManager default request: 'Enter number ', each asString) asNumber ]
The result will be an Array of the entered numbers.
Or, without using collect:
and building up the collection yourself:
numbers := OrderedCollection new.
10 timesRepeat:
[ numbers add: (UIManager default request: 'Enter next number') asNumber ].
numbers do: [:each | Transcript show: each ].
You might also like UIManager default chooseFrom:
. Browse the UIManager class and try out the various methods.
Note that Pharo's playground (called workspace in most other Smalltalks) already does what a REPL does, albeit it is not limited to line-based input. You can type Smalltalk expressions, evaluate them and have the results printed there. I am aware that this information does not give you the experience of porting your calculator app from C++. But I guess the way how the I/O works, or rather the interaction with the user, is not the essence of the programs you are trying to port, right? So you might as well write a class Calculator
, in which you implement your calculator app, taking a String as input and returning the resulting number, and then invoke it from the playground by evaluating an expression like the following:
Calculator new calculate: '3 + 4'
If you really, really want to stick to console stuff and miss the benefits of the usual Smalltalk IDE and the experience of learning and using it, you might be better off with GNU Smalltalk. I think there are ways to create console applications with Pharo as well, but I would not recommend that to Smalltalk newcomers and I will leave that answer to someone who has already done it once.
Solution 2:[2]
You can use Pharo and get immediate feedback from the terminal like this:
? ./pharo Pharo.image eval "6+5"
11
Whatever you have between these quotes is being used as source by the compiler and the answered object will be printed to the stdout. In that example, it will be using SmallInteger>>asString
behind the scenes.
For making a REPL, you don't need a lot. If you want to take a look, I've made REPLEndpoint using the Zinc HTTP server. In REPLEndpoint >> post
you'll find the part where it uses the snippet you send to be evaluated:
snippet := '6+5'.
answer := OpalCompiler new evaluate: snippet.
answer
And answer
will be the 11
SmallInteger instance you'd expect.
For additional hints on how your command line based REPL, take a look at the EvaluateCommandLineHandler
class as it implements the basic step of what a REPL would do.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | JayK |
Solution 2 | Sebastian Sastre |