Rewriting a script into a callable method
After you have written your small test script and tested it interactively, it is often useful to convert it to a reusable method. The whole point about Methods is provide further modularization of your programs into more easily understood units of code.
Using the "Fun with MD5 and Random" example code posted on this blog by Samuel Montgomery October 3rd, 2007, as a starting point I wanted to use that routine as a callable method.
(Incidently 'method' is really another name for Procedure or Function in other languages)
Here is the original code : random.st
| d i l s |
i := 20.
d := '0123456789abcdefghijklmnopqrstuvwxyz'.
l := d size.
s := String new: i.
1 to: i do: [ :x |
s at: x put: (d at: (Random between: 1 and: l))
].
s printNl.
which you use thus:
$ gst -f random.st 'xo3vs65ntz3qcfmg9z17' $
which returns one (1) randomly generated string.
To convert this to method that our program can call, firstly give the random code a method name
printRandom [
| d i l s |
i := 20.
d := '0123456789abcdefghijklmnopqrstuvwxyz'.
l := d size.
s := String new: i.
1 to: i do: [ :x |
s at: x put: (d at: (Random between: 1 and: l))
].
s printNl ]
then 'wrap' it around with the following lines, and add a suitable comment line
Object extend [ ]
giving :
" random-2.st prints a random generated string from inside the method "
Object extend [
printRandom [
| d i l s |
i := 20.
d := '0123456789abcdefghijklmnopqrstuvwxyz'.
l := d size.
s := String new: i.
1 to: i do: [ :x |
s at: x put: (d at: (Random between: 1 and: l))
].
s printNl ]
]
5 timesRepeat: [ self printRandom ].
save as random-2.st, and execute
$ gst -f random-2.st 'ko7vkzgea32qe155817k' 'bsx89fxasgvi4b6dsh39' 'z7vjtzca40feosi580rc' '2l2655n3chd3l6dueawi' 'zy7ryhpwyi7yyz289pd3' $
The "Object extend [ ]" block , adds your method to the base gst image (in memory),and therefore printRandom becomes part of your current execution session and can now be used from your program as if was a built in smalltalk method.
Check the documentation to load your own code into a base image and make your own image which becomes your base image for further development.
The line of code ,
5 timesRepeat: [ self printRandom ].
which is our main program in this script, simply calls our method 'printRandom' 5 times and outputs the results onto the konsole.
Now we have a working method, we can now use it in any program we wish to write, and not have to recode the random task again.
Below, random-3.st, shows two ways in which our method can be called. Note, I renamed it "genRandomStr" as I felt a better name as required, because that's what it does - generates a random string.
" random-3.st prints a random generated string returned by the method "
Object extend [
genRandomStr [
| d i l s |
i := 20.
d := '0123456789abcdefghijklmnopqrstuvwxyz'.
l := d size.
s := String new: i.
1 to: i do: [ :x |
s at: x put: (d at: (Random between: 1 and: l))
].
"s printNl."
^s.]
]
" ========== main code =========== "
5 timesRepeat: [ s := self genRandomStr.
Transcript show: s ; nl].
" using a local variable, s, to retain the returned random string "
Transcript cr.
5 timesRepeat: [ Transcript show: self genRandomStr ; nl].
" print the returned random string , not retained just printed "
Here the program calls the genRandomStr in two ways, one way keeps the returned string, the other simply passed the returned string to the Transcript ( standard print method )
$ gst -f random-3.st yjrsijee56tvzgi9o0l8 wcwhmrft19jkkto9ctbd yyr8ei4t8agfaegerbiy 7b26rb71xn7sf9azqe5z 6yrf1evzdyfll9domjbb 43l3b7hb1atq7yioeev4 3hvsvtbyjis4jo9tbq4s o5a71qticjo1gh392zui yt1ntnt0xbsl4ykjrebv l7ituc34n62vzphaefr0 $
Defining more than one method
You can define as many Methods as you require to be added to the Object by adding more methods in the
Object extend [ ]
Below I have defined two versions of genRandomStr, the code remains the same, but they have different Methods names as I'm just illustrating the concept here.
" random-4.st prints a random generated string returned by the method
note: there are two extend methods defined, only their names are different "
Object extend [
genRandomStr [
| d i l s |
i := 20.
d := '0123456789abcdefghijklmnopqrstuvwxyz'.
l := d size.
s := String new: i.
1 to: i do: [ :x |
s at: x put: (d at: (Random between: 1 and: l))
].
^s.]
genRandomStr2 [
| d i l s |
i := 20.
d := '0123456789abcdefghijklmnopqrstuvwxyz'.
l := d size.
s := String new: i.
1 to: i do: [ :x |
s at: x put: (d at: (Random between: 1 and: l))
].
^s.]
] " end extend "
" ========== main code =========== "
5 timesRepeat: [ s := self genRandomStr.
Transcript show: s ; nl].
" using a local variable, s, to retain the returned random string "
Transcript cr.
5 timesRepeat: [ Transcript show: self genRandomStr2 ; nl].
" print the returned random string , not retained just printed "
I followed up on my blog at http://methodsandmessages.vox.com/library/post/rewriting-the-rewriting-a...
Your correct in your observations re: not smalltalkish code.
I decided to leave the original code alone because its very
clear in its intent, and did work as is, and sometimes not being smalltalkish aids the newcommer.
Your revised version is much better Smalltalk,
Your observation on the usage of variable names is really important, many programmers don't appreaciate the value
of descriptive names. I try to avoid the use of i & l, n & m characters in particular as variables because
a) not very descriptive & b) easily mistaken
for the other when reading code.
Happy to use X as a temp inside iterators tho !
Thanks for your additional input into helping explain Smalltalk!