I really love Rebol for saving me time doing tedious tasks the easy way. For example last time, we learnt how to download and parse a stock symbol from Google Finance. Now if we want to download multiple symbols and combine this kind of tasks with others, instead of writing a big script, we can use a Template Design Pattern by combining different types of taks at will. I took 100% inspiration from this code skeleton and just added some implementation samples.
So in this example, we suppose that we have two types of tasks:
- downloading a stock
- listing the downloaded stocks
The Robot below is a Rebol Object which will serve as a base Object for Real Workers (Remember Rebol is a Prototyped-Base Language: there are only Object Instances, no Class):
;this ROBOT will serve as prototype to create other Robots
ROBOT: make object! [
stock-symbols: [] ; property to store the list of stock-symbols
;task1 function
download: func [stock-symbol] [
url: to-url rejoin [http://www.google.com/finance/historical?q= stock-symbol "&output=csv"]
target-file: to-rebol-file rejoin [stock-symbol ".csv"]
write/lines target-file read/lines url
append stock-symbols stock-symbol
]
;task2 function
list: func [][
foreach symbol stock-symbols [print symbol]
]
;core engine
run: func [task-list][
stock-symbols: [] ; reset the stocks list
do bind task-list 'self ; this is the hard part to understand see explanation below
]
]
Did you see the bind instruction ? As we told you in previous article, this is the hidden source of Rebol’s Power. Why do we need to bind code to ’self (self is a variable which represents a pointer to the object himself). Because Code is a block of Rebol’s Instructions (see tasks-list1 and tasks-list1 examples below) which will contain Words which would be unknown to the Run function if they weren’t declared with Bind. As for do, it allows dynamic interpretation of code passed as argument to it.
You can now copy and paste the code above in Rebol Console and then test it with Worker1 which is an Object derived or inherited from Robot and which will be assigned tasks-list1:
tasks-list1: [
download "GOOG"
download "YHOO"
download "MSFT"
list
]
Worker1: make ROBOT []
Worker1/run tasks-list1
Nothing now prevents you from creating other workers with other task-lists:
tasks-list2: [
download "AAPL"
download "ORCL"
list
]
Worker2: make ROBOT[]
Worker2/run tasks-list2
In conclusion, with this Template Design Pattern, you can easily modularize your functions with the finest granularity, extend the Robot with many other functions, and adapt your workers to your evolving needs by just changing their list of tasks or just their sequence of execution.
















I was interested in the map-reduce in Rebol but it appears to be a broken link. Has this disappeared totally now form the site?
It’s a future article that is not yet finished so wait a little bit