Archive for the tag 'Ruby'

Simple File Based Application Configuration

I thought this was too simple to bother posting about, but someone requested it, so here it is. Having made my journey to Linux about a year ago, I’ve found a new appreciation for the simplicity of plain old text files and the file system in general.

Some of the tools I’ve come to rely on like Daemontools from Daniel Bernstein also show this appreciation of the Unix way, small simple reliable tools that just work and are configured easily with plain text files. The most recent versions of Apache have also broken up the monolithic httpd.config into much smaller simpler individual files spread out over various directories that greatly ease automation by keeping individual site settings in separate files and using simple symbolic links to enable or disable individual sites.

Inspired by the simplicity and ease of managing these tools, I decided my Smalltalk programs, while ungodly easy to write, were much too hard to configure and deploy because configuration was based either on code in the image or in the case of Seaside, its custom configuration system, neither of which are simple or easy to move around between images and servers. I also like how Ruby on Rails configuration system allows multiple configurations that you can easily switch between to run your code in your various environments.

Rather than trying to design some ultimate configuration system, I just looked at how I write and deploy *my* applications, which is always one image per application in its own directory (possibly launched multiple times on various ports) and decided the simplest thing that could possibly work for me was just a directory named config, in my image directory, with three subdirectories named prod, dev, and test, and a single file named config which tells me which config subdirectory is active.

So I’ll declare a configuration class…

Object subclass: #SSConfig
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'SentorsaSeaside-Configuration'

and a class side #create method to setup this structure on the filesystem…

create
    | configDir |
    configDir := (FileDirectory default directoryNamed: #config) assureExistence.
    FileStream
        forceNewFileNamed: (configDir fullNameFor: #config)
        do: [ : f | f nextPutAll: 'dev' ].
    (configDir directoryNamed: #prod) assureExistence.
    (configDir directoryNamed: #dev) assureExistence.
    (configDir directoryNamed: #test) assureExistence

Next, I want a simple dictionary style API, “SSConfig at: #someSetting”, so I’ll need the core class side method #at: which grabs the current configuration and uses the key you hand it to looks for the file name that matches, opening it in read only mode if it exists or simply creating it if it doesn’t.

at: aKey
	| currentConfig configDir value |
	currentConfig := FileStream
		readOnlyFileNamed: ((FileDirectory default directoryNamed: #config) fullNameFor: #config)
		do: [ : f | f contentsOfEntireFile ].
	configDir := (FileDirectory default directoryNamed: #config) directoryNamed: currentConfig.
	value := (configDir fileExists: aKey)
		ifTrue:
			[ FileStream
				readOnlyFileNamed: (configDir fullNameFor: aKey)
				do: [ : f | f contentsOfEntireFile ] ]
		ifFalse:
			[ FileStream
				forceNewFileNamed: (configDir fullNameFor: aKey)
				do: [ : f | f contentsOfEntireFile ] ].
	^ (value endsWith: Character lf asString)
		ifTrue: [ value allButLast ]
		ifFalse: [ value ]

Next I want to be able to ask for a value and provide a default in case there is no configured value, built simply upon the previous method…

at: aKey default: aValue
    ^(self at: aKey)
        ifEmpty: [ aValue ]
        ifNotEmptyDo: [ : it | it ]

I also want to be able to ask for a config value typed to a boolean (SSConfig can: #useBlaBla) for the common case of true/false settings, another simple method built upon #at:…

can: aKey
    ^(self at: aKey) = 'true'

And of course, having strings and booleans, I now want a couple of simple methods for asking for integers from config…

numAt: aKey
    ^(self at: aKey)
        ifEmpty: [ 0 ]
        ifNotEmptyDo: [ : it | it asInteger ]

numAt: aKey default: aValue
    ^(self at: aKey)
        ifEmpty: [ aValue ]
        ifNotEmptyDo: [ : it | it asInteger ]

These are all class side methods, and so far I’ve not found the need for anything more than strings, bools, and integers. If I do, I’ll extend it more, however, this seems to be all I need for all of my configuration needs thus far. It’s simple, every setting is its own file, and it allows me to easily switch between various configs and easily share configurations between various images with nothing more than a simple file copy. I can also easily edit the configuration from the shell, where I do most of my administration tasks.

NOTE: This method is not application aware, so it won’t work well if you run multiple applications within a single image, but I’m not writing code for use cases I don’t have and it works well for how I deploy my applications.

New GNU Smalltalk Site Launched

GNU Smalltalk has launched a new site. I thought it was about time to give it a try so I can write my shell scripts in Smalltalk. I work in Windows but I use Cygwin so I can have a real shell handy, fortunately GNU Smalltalk runs under Cygwin. So I fire up a shell and grab the latest version, unzip and untar it…

wget ftp://ftp.gnu.org/gnu/smalltalk/smalltalk-2.3.6.tar.gz
gunzip smalltalk-2.3.6.tar.gz
tar -xf smalltalk-2.3.6.tar

So far so good. The instructions say I need autoreconfig, so I fire up Cygwin setup and hit the Devel category and install it, just to be safe I install gcc compilers for C and C++ as well. Time to build Smalltalk (that sounds weird to me).

autoreconf -fvi
./configure
make

Takes a minute, checks a gazillion things, but all is well, build seems to work fine. Time to run the unit tests…

make check

Good to go, so lets install…

make install

OK, now just type “gst” to get a REPL, play around for a bit, and write my first simple shell script, a quick loop printing 1 to 10000 on stdout…

#!/usr/local/bin/gst -f
(1 to: 10000) do:[:it | it printOn: stdout].
!

Sweet, works like a charm. I can now fall back on Smalltalk for shell scripting instead of ruby or pearl when I need more power than simple bash scripts.

Stealing a sample from the Wiki shows a nice scripting syntax making use of blocks for declaring class and method bodies…

Object subclass: Person [
    | name age |
    Person class >> name: aString age: anInteger [
        ^(self new)
            name: aString;
            age: anInteger;
            yourself
    ]

    name [ ^name ]
    name: aString [ name := aString ]
    age [ ^age ]
    age: anInteger [ age := anInteger ]

    printOn: aStream [
        aStream << ('%1 (%2)' % {name. age})
    ]
]

I think I like it! Only time will tell, but I think this will be my new scripting language of choice.

On Simple Functional Idioms

I ran across an post by David Altenburg about the enumerate, map, filter, accumulate pattern. These are certainly common functional techniques, but they’re also common Smalltalk techniques. We call them do:, collect:, select:, and inject:into:.

He showed a Java implementation of a simple and common programming problem…

int maxSalary = 0;
for (Employee employee : employees) {
  if (Role.PROGRAMMER.equals(employee.getRole())) {
    int salary = employee.getSalary();
    if (salary > maxSalary) {
      maxSalary = salary;
    }
  }
}

Comparible to a C# 1.0 version…

int maxSalary = 0;
foreach(Employee employee in employees) {
    if(employee.Role == Role.PROGRAMMER
        && employee.Salary > maxSalary) {
        maxSalary = employee.Salary;
    }
}

Then he does a Scheme version using a more functional style…

(define (salary-of-highest-paid-programmer records)
  (accumulate
      max 0
        (map salary
          (filter programmer? records))))

And a Ruby version of similar style, note the Smalltalk’ishness of it…

employees.
  select {|emp| :programmer == emp.role }.
    map {|emp| emp.salary }.
      inject {|m, v| m > v ? m : v}

And for comparison here’s a Smalltalk version…

(employees
    select: [:emp | emp role = #programmer ]
    thenCollect: [:emp | emp salary ])
        inject: 0 into: [:a :b | a max: b ]

Though if I found the pattern that common I’d define a quick helper method on Collection to clean up the syntax to this…

employees
    select: [:emp | emp role = #programmer ]
    collect: [:emp | emp salary ]
    inject: 0 into: [:a :b | a max: b ]

What’s interesting about them to me is really the difference between the Java/C# approaches and the more composable Scheme/Ruby/Smalltalk style. Because Java/C# 1.0 lack first class functions (C# actually has them now in 2.0 and a nice lambda syntax in 3.0) and a literal syntax for declaring them, everything ends up being a special case of for/foreach. They lack the ability to factor out common patterns like select:, collect:, and inject:into: into higher order functions.

As a side effect, select: turns into nested if’s and a loop, collect: into a temporary variable and a loop, and inject:into: into both an if, a temporary variable, and a loop. You end up writing these patterns inline over and over rather than just reusing existing versions from the base library.

Languages that can’t support and make idiomatic the use of higher order functions, aren’t worth using these days in most domains. They’re just too damn much work. However, using functional techniques doesn’t at all mean using a functional language. All of these work quite well in good object oriented languages like Smalltalk and Ruby.

A Squeak Smalltalk Development Example

Stephan Wessels has put up a very large tutorial showing the complete test driven development of a game in Squeak. It covers quite a few things new Squeakers will want to know such as using SUnit to do test driven development, using Morphic to create Squeak widgets, using the debugger, and packaging the code with Monticello. It’s a great tutorial and I’m sure will become a popular resource.

However, despite the awesome effort (which I do appreciate), I have some problems with it. As with many other Squeak tutorials, it makes the mistake of using a standard Squeak image as you’d find on Squeak.org. This only helps further propagate the impression among newbies that Squeak is ugly, old fashioned, and lacking in all the features they expect from a more modern IDE. What you see in the screenshots is not a Squeak I’d use. Plain black code, ugly fonts, no intellisense, no use of the Refactoring Browser, no Shout Workspace.

Most developers who use Squeak would have a plethora of extra tools and utilities installed that make developing a much nicer experience than what you see in this tutorial. Do yourself a favor and start your Squeaking with a real developer’s image loaded with all the proper goodies like the SqueakDev image maintained by Damien Cassou.

Squeak.org still hasn’t figured out that its core audience should be developers, not children. They don’t seem to realize the base image they distribute actually scares away more people than it encourages to join the community. Though they do have a link to Damien’s SqueakDev image, they don’t encourage it like they do the base image, a mistake that leads new developers to open up Squeak for the first time, browser a tutorial or two, and toss it aside as a silly toy, never having seen the real power or beauty that is Smalltalk.

So all you developers out there using Squeak, please, stop showing people ugly images. Marketing matters, looks matter, and that stuff scares people away. Load up some decent fonts, setup the minimum *required* goodies like Shout, the Refactoring Browser, and ECompletion. And if you aren’t using these goodies, you should be, and you shouldn’t be making tutorials without them because it gives people a false impression of what Squeak is. Squeak is an awesome development environment that sadly doesn’t come out of the box that way, you have to start with the right box or learn to build your own.

Squeak.org could learn a lot about marketing Squeak by looking at how rubyonrails.org markets Rails. If there’s one thing Ruby does vastly better than Smalltalk, it’s marketing. Smalltalk continues to languish not because of technical merits, but because of bad marketing. Beaten by Java, and now beaten by Ruby, by marketing alone.

Next Page »