How to store information to a log file.
Let’s say you want to keep a log of data or events in a file:
You can use this super-efficient method (and it’s worth remembering):
write/append log-file append mold/only data newline
What makes this efficient is that you are not reading the entire log file first, you are just appending a record (a line) to it.
Here the data can be a block of information or just a word or string. The mold converts anything to a REBOL-readable string with the /only removes the outermost brackets “”. We then append a newline (line terminator) to it.
Many programmers create a function called log (as in the verb “to log”) that writes out log events this way. Here is one that also adds a time-stamp to the start of each line:
log: func [data] [ write/append log-file rejoin [now " - " mold/only reduce data newline] ]
The reduce evaluates the data block in order to get the actual contents of variables.
You can now just write:
log "some event"
log ["some event" 1234 http://example.com]
Here’s how log might appear in a program that logs user account actions:
;The variables: user: "Bob" pass: "password" action: 'new-user account: 1234 website: http://www.rebol.com ... log [user pass action account website]
If you open the log file using an editor, you’ll now see:
22-Sep-2010/9:32:54-4:00 - "Bob" "password" new-user 1234 http://www.rebol.com
In REBOL 3, if you want to shorten up the time-stamp a bit, you can use now/utc to just store the universal time. If you want to hide the password, there are a few ways to do so, but we’ll explain that later.
Reading and processing a log file is the subject of another blog, but here are a few hints, in case you’re interested:
log-lines: read/lines log-file ; a block of lines (strings) foreach line log-lines [probe load line]
And, here’s another:
log-data: load log-file ; a continues block parse log-data [ some [copy line [skip [to date! | to end]] (probe line)] ]
How to save multiple data records to a file and load them back again.
Let’s say you have a block of name records sort of like this:
group: [ [1 "Bob" "Smith" 12-Aug-1965 "Seattle" WA member] [2 "Tom" "Able" 20-Feb-1955 "San Jose" CA author] [3 "Jen" "Jones" 16-Jun-1972 "New York" NY leader] [4 "Sal" "Baker" 25-Oct-1975 "Boston" MA member] ]
To save all of these to a file:
save/all %group.r group
Take a look at the group.r file in an editor, and you’ll be able to see the same records as above.
To load back the records you saved above:
group: load/all %group.r
Don’t forget to use the /all refinement or you’ll have some problems at times.
Now you have an easy way to save and access data from your programs. This technique even works well for files of more than 100 thousand records!
This example shows how to save data out to a file and loading it back again.
For simple single values, you just save them out to a file.
To store an integer:
num: 123 save %num.r num
To store a string:
name: "Tom Smith" save %name.r name
You can use any suffix for the file. We use
.r here because the data is in REBOL format, but the suffix doesn’t matter.
Now, you use load to get back the values.
To load the integer:
num: load %num.r print num 123
To load the string:
name: load %name.r print name Tom Smith