Filenames and Inter-Smalltalk Portability
Troy Brumley, in his blog post File access demo from VW to Squeak (2006-06-03), picks up on some example VisualWorks code posted by James Robertson a day earlier (Simple File I/O Demo, 2006-06-02.) Troy's examples show how to code the same thing in Squeak.
But there is another option: Use the Passport inter-Smalltalk portability library that was implemented in order to make it possible to host The Chronos Date/Time Library on VisualWorks, Squeak and Dolphin. Using Passport, the code will work unchanged in VisualWorks, Squeak and Dolphin.
Here's the Passport version (with Jim's original variable names unchanged, even though they aren't the best names for use with Passport):
"write a simple file"
file := 'myTestFile.txt' asResourcePath.
stream := file writeStream.
stream nextPutAll: 'Line 1'.
stream nextPut: Character cr.
stream nextPutAll: 'Line 2'.
stream nextPut: Character cr.
stream nextPutAll: 'Line 3'.
stream nextPut: Character cr.
stream close.
"read the entire file"
file := 'myTestFile.txt' asResourcePath.
contents := file value.
^contents.
"read line by line"
file := 'myTestFile.txt' asResourcePath.
stream := file readStream.
lines := OrderedCollection new.
[stream atEnd]
whileFalse: [| line |
line := UtilityFunction nextLineFrom: stream.
lines add: line].
stream close.
^lines.
"finding the file"
directory := '.' asResourcePath.
files := OrderedCollection new.
directory contentsDo: [:resourcePath | ('myTest*' match: resourcePath suffixString) ifTrue: [files add: resourcePath]].
^files.
(To see Jim's original VW code, follow this link: Simple File I/O Demo (VW code))
Passport not only makes it possible to write the same file name logic portably among different Smalltalk versions, it also makes it possible to use the same code regardless of whether the host operating system is Unix, MacOS X or Windows. But to do that, there are some constraints:
Firstly, either you can't use absolute pathnames, or else the absolute path must be constructed at run time by appending a well-known path suffix onto a path prefix that is supplied as a parameter at run time (and which will necessarily differ from one host OS to another, and often also even between different computers, even when they all use the same OS.)
Secondly, the relative path suffix must be constructed using a Pathname, as in the following example:
| resourcePath stream |
resourcePath := (Pathname fromString: 'test/folder1') asResourcePath.
resourcePath makeDirectory.
resourcePath := resourcePath, 'junk.txt'.
"The ResoucePath is now [./test/folder1/junk.txt]"
stream := resourcePath newWriteStream.
stream nextPutAll: 'This is a test.'.
stream close.
Typically, one would construct a ResourcePath using a path prefix obtained from your application's configuration parameters, using a well-known (or deterministically computable) path suffix. For example, the Chronos Date/Time Library might construct the path to a Chronos time zone ruleset file as follows:
(ResourcePath
namespace:
(EnvironmentFacade current
valueOfEnvironmentVariableAt: 'CHRONOS_PATH')
pathname:
(Pathname
fromString: 'time-zones/rulesets/Pacific/Honolulu'))
appendingExtension: 'tzn'
On the Windows machine I use for Chronos development, doing a "print it" on the above example would have the following result: H:\Dev\Smalltalk\Chronos\Chronos Versions\VisualWorks\Chronos\time-zones\rulesets\Pacific\Honolulu.tzn.
The Squeak version of Passport is available as two of the files in the version of Chronos.zip distributed for Squeak (namely, "Passport-Kernel.st" and "Passport-Squeak.st.") It's also available from SqueakSource (in the Chronos project.)
The VisualWorks version can be obtained from the Cincom Public StORE. It can also be filed out or parcelled out after installing the VisualWorks version of Chronos (it's in the packages Passport-Kernel and Passport-Kernel-VW.)
The Dolphin version of Passport is available on request (requests (at) chronos-st (dot) org).
No comments:
Post a Comment