Feeds:
Posts
Comments

Archive for August, 2007

A few weeks ago I discovered the Code Kata website. Working through a few of these exercises may help me improve my very basic squeak which I have wanted to learn properly for a while. As a recovering perler, the first kata that really appeals is kata 4 (data munging).

I started with the following:

  1. Damien Cassou’s fantastic Squeak development image with code completion, syntax highlighting and much more. That is available here.
  2. A pure smalltalk regex package. If you download this mcz and drag it and drop it onto your image you are good to go.
  3. The Terse guide to Squeak

After working through the problems the first time in the workspace, I wanted to come up with a more generic solution. The obvious one is to have a stream method that iterates over lines. There are a number of ways of doing this. With some inspiration from the STL algorithm library here is a class with a single class method:

StreamAlgorithms>>class

on: aStream eachLine: aBlock
	| line |
	aStream position: 0.
	[ (line := aStream nextLine) isNil ] whileFalse: [
		aBlock value: line
	]

This is used as following (actual solution to the Kata elided):

| fp |
Transcript clear.
fp := CrLfFileStream readOnlyFileNamed: 'c:/dev/weather.dat'.
StreamAlgorithms
       on: fp
       eachLine: [ :line | Transcript show: ('[', line, ']') ; cr ].
fp close.

Alternatively, here is a class that wraps a stream.

Object subclass: #ExtendedStream
	instanceVariableNames: 'stream'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Katas'

These are the instance methods

stream
	^ stream

stream: anObject
	stream := anObject

eachLine: aBlock
	| line |
	self stream position: 0.
	[ (line := self stream nextLine) isNil ] whileFalse: [
		aBlock value: line
	]

And the class methods…

ExtendedStream>>class

"'Constructor'"
on: aStream
	^ (self new) stream: aStream

"I liked this class method from StreamAlgorithms"
on: aStream eachLine: aBlock
	| line |
	aStream position: 0.
	[ (line := aStream nextLine) isNil ] whileFalse: [
		aBlock value: line
	]

The client code for this is:

Transcript clear.
fp := ExtendedStream on: (CrLfFileStream readOnlyFileNamed: 'c:/dev/weather.dat').
fp eachLine: [ :line | Transcript show: ('[', line, ']') ; cr ].
fp close.

Possibly the best way is to put eachLine: as an instance method on the stream class but I’m not comfortable messing with the core libraries just yet.

Read Full Post »

Follow

Get every new post delivered to your Inbox.