PackageDescription: Herl


Last published: June 4, 2010 by 'tgriggs'

Defines 1 Classes
Extends 10 Classes

Herl is a scripting inspired set of extensions to the Smalltalk library, that enable one to do things similar to what one might do in shell scripts. It is *just* Smalltalk. It abuses the builtin literal object types.

Thanks to Ken Treis for the name. It is a play on the venerable Perl, and on our gut reaction to seeing code like this, all terse and short with lots of infix characters.

Like other scripting languages, there is no real design to it, instead making it up as I go, using real world scripting challenges as input for how to evolve it.

- Files
A number of methods have been added to String, which result in them being coerced to Filenames. Always PortableFilenames actually, which allow environment variables to be in them using $(VAR_NAME) substitution.

Building file paths:
'$(HOME)' / 'subdir'

Changing current directory:
'path' cd

Copying files:
'path' cp: 'targetPath' (does unix cp -Rpf semantics)

Listing directories:
'directory' ls: 'regex-pattern' (returns array of files in directory that match regex-pattern)

Moving/Renaming files:
'path' mv: 'targetPath' (does unix mv semantics)

Removing files:
'path' rm (does unix rm -rf semantics)

- Executing other programs
We use arrays for this. An SequenceableCollection may be executed as a program, where the first arugment is the program name, and the rest of the Array is the arguments. Each of the remaining args is sent the #forExec message which coerces it to a string (for example, Filename objects turn into absolute resolved strings). Example:

#(tar -xvf 'file.tgz') exec

The exec runs tar with the arguments '-xzf' and 'file.tgz'. In the example, I'm taking advantage of the fact that VW will interpret simple keywords in literal arrays as symbols, so the above is equivalent to #(#tar #'-' #xvf 'file.tgz'). In the case of the -, code exists explicitely to note lone - symbols and fold them with the following argument. Herl builds on the ScriptingSupport package, so it is possible to build programatic arrays up easily for execution:

(#(tar -xvzf) & tempVarThatHoldsOutputName) exec

- Environment Variables
You can set, unset, and get environment variables using the #setenv: and #unsetenv and #getevn messages. Examples:

'PKG_CONFIG' setenv: rootDir / 'bin' / 'pkg-config'
'PKG_CONFIG_PATH' unsetenv.
'PATH' getenv

- Regex Matching
Any methods that need to do matching (ls: for example) use regex matching, not Smalltalk match: utilities. Also you can regex match strings easily with the two binary methods ?= and =?. The Regex pattern goes near the ?. Example:

'.*' ?= 'abc'
'abe' =? 'ab[cd]'

- Parsing
Breaking strings into sequences of fields can be done using the -@ method. A single character argument, or a string of multiple characters may be used as the argument. Example:

'foo bar baz' -@ Character space
'foo/bar\baz' -@ '\ /'

- Sorting
Collections may be #sortBy: (in place) or #sortedBy: (new collection). The argument is an array of unary evaluable objects. You can cull symbols or use blocks. For example:

sequenceOfArraysOrNames sortBy: #size & [:array | array first] "sorts them first by size, and if size matches, then by the value of the first element"

- Accessing Sequence Elements
In scripting, we tend to abuse arrays as data structures, rather than make first class objects. This tempts one to add #second, #third, #fourth methods, and so on. Herl instead adds the following unary messages to SequencableCollection:

_1, _2, _3, _4, _5, _6, _7, _8, _9


('Hi there friend' -@ Character space) _2 "returns 'there'"

You may also use the general _: method, which takes an integer argument and is equivalent to at:, but also allows access from the back of the sequence. Access from the back is "offset" based. Examples:

#(10 20 30 40) _: 3 --> 30
#(10 20 30 40) _: 0 --> 40
#(10 20 30 40) _: -2 --> 20