aaron.harnly.net

each_line do |line| in Scala

March 27th, 2007 by aaronharnly

I’m so used to the each_line idiom in Ruby, I felt utterly lost in Scala without it.

Here’s an approximation of it, though I’d love to hear that there’s an even more scala-ish (scalic?) way of doing this:

def eachline(stream : InputStream)(f : String => Unit) { val buf = new BufferedReader( new InputStreamReader( stream ) ) var line = buf.readLine while (line != null) { f(line) line = buf.readLine } }

I use this with a block as so: eachline(System.in) { line => Console.println(line) }

Not bad, but it could be better, I think. Can I tickle this to be a method on streams, instead of a funny little function sitting on its own?

each_line do |line| in Scala

March 27th, 2007 by aaronharnly

I’m so used to the each_line idiom in Ruby, I felt utterly lost in Scala without it.

Here’s an approximation of it, though I’d love to hear that there’s an even more scala-ish (scalic?) way of doing this:

def eachline(stream : InputStream)(f : String => Unit) { val buf = new BufferedReader( new InputStreamReader( stream ) ) var line = buf.readLine while (line != null) { f(line) line = buf.readLine } }

I use this with a block as so: eachline(System.in) { line => Console.println(line) }

Not bad, but it could be better, I think. Can I tickle this to be a method on streams, instead of a funny little function sitting on its own?

Sharing the wealth: My dotfiles

March 26th, 2007 by aaronharnly

It is the fashion these days to share your .bashrc, so I thought I’d do so.

Here is my .bashrc in all its glory.

And here is a typical prompt it produces:

The first little box there just displays the login information — whether I’m local or remote, and from which host. That’s handy if I’m bouncing between servers and have forgotten whether I’m connected to machine C via machine B, or directly from A, etc.

Also of interest there is an updated version of this MacOSXHints.com suggestion of mine, which lists available GNU screen sessions.

Some other little functions I use daily are pathappend, pathprepend, and try_export, which simply add a directory (if it exists) to the beginning or end of a given env variable, usually $PATH.

So, for example, I have these lines:

path_prepend $HOME/software/crossplatform/bin
try_export "/usr/local/java/java1.5" JAVA_HOME
try_export "/System/Library/Frameworks/JavaVM.framework/Versions/1.5/Home/" JAVA_HOME

which I think makes for a much tidier way to conditionally set a variable depending on which platform I happen to be logged into. IMHO.

Anyway, enjoy.

Using snippets in Textmate templates

March 19th, 2007 by aaronharnly

Pursuant to the post below, I found myself creating a simple Scala bundle for Textmate, as there isn’t one at the moment. (Getting in on the ground floor!)

The Textmate snippet system is a wonderful creation — simple, delightful, and helpful. Unfortunately, the templating system is not nearly so nice — just a Perl one-liner to substitute in some environment variables, and no snappy tab-tab autofill magic.

Then I ran across this great post by Henrik Nyh, in which he scrapes together a little Applescript to create a Textmate template as a snippet.

However, I found myself wanting both some templated boilerplate, with variable substitution, and some snippetized text below. This proved a little trickier than I first thought, since the Applescript inserts at the top of the document, and it would require a nasty keypress script to insert the snippet below.

So, I came up with a slightly modified version of Henrik’s system, which supports a template_in.txt file with the usual variable substitutions, as well as a snippet below.

The template script looks like this: if [[ ! -f "$TMNEWFILE" ]]; then TMYEAR=date +%Y \ TMDATE=date +%Y-%m-%d \ TMUSERNAME=niutil -readprop / /users/\$USER realname \ TMTEMPLATEOUTPUT=$(mktemp “/tmp/tmtemplate_XXXXXX”)

perl -pe ’s/\${([^}]*)}/$ENV{$1}/g’ \ < templatein.txt > “$TMTEMPLATE_OUTPUT”

touch “$TMNEWFILE”

{ # Insert the template & snippet!
osascript "${TM_BUNDLE_SUPPORT}/load_snippet.scpt" "$TM_TEMPLATE_OUTPUT" "snippet.txt" 
} &>/dev/null &

fi

and the Applescript is modified to this: on run args set templateoutputfile to (item 1 of args) set snippet_file to (item 2 of args)

-- retrieve the template and snippet text
set existing_text to read (POSIX file (template_output_file)) as «class utf8»
set loaded_snippet to read (POSIX file (snippet_file)) as «class utf8»

-- insert both into the document
tell application "TextMate"
    insert existing_text
    insert loaded_snippet with as snippet
end tell

-- remove the temporary file
do shell script "rm \"" & template_output_file & "\""

end run

You can download Snipplate2 (AWH) here.

Scala is my new Ruby

March 19th, 2007 by aaronharnly

Scala is my new Ruby, i.e. the language I love to tinker in. Rather more practical, too, as the fact that Ruby is dog-slow has gotten in the way of my work more than once recently.

List all application versions

March 12th, 2007 by aaronharnly

Here’s a nice little one-liner for listing the current version and installation date of every application on your OS X system, using the wonders of Spotlight:

mdfind “kMDItemKind == ‘Application’” | perl -ne ‘chomp; print “\”$_\”\n” ‘ | xargs mdls -name kMDItemFSContentChangeDate -name kMDItemVersion -name kMDItemDisplayName -name kMDItemPath | perl -pe ’s/^\/.+/”-” x 20/e’

Sample output:

kMDItemDisplayName         = "MarsEdit.app"
kMDItemFSContentChangeDate = 2006-03-13 22:58:25 -0500
kMDItemPath                = "/Applications/3rdPartyApps/Write/MarsEdit.app"
kMDItemVersion             = "1.1.2"
--------------------
kMDItemDisplayName         = "OmniWeb.app"
kMDItemFSContentChangeDate = 2007-02-14 17:23:51 -0500
kMDItemPath                = "/Applications/3rdPartyApps/Connect/OmniWeb.app"
kMDItemVersion             = "5.5.4"
--------------------
kMDItemDisplayName         = "CandyBar.app"
kMDItemFSContentChangeDate = 2006-04-14 18:40:52 -0400
kMDItemPath                = "/Applications/3rdPartyApps/Tinker/prettify/CandyBar.app"
kMDItemVersion             = "2.6.1"
--------------------
kMDItemDisplayName         = "Vienna.app"
kMDItemFSContentChangeDate = 2007-01-27 13:38:17 -0500
kMDItemPath                = "/Applications/3rdPartyApps/Connect/Vienna.app"
kMDItemVersion             = "2.1.1.2109"

Triple-Quote to use a shell variable in awk

March 12th, 2007 by aaronharnly

Just a little note: Found myself wanting to print a shell variable as part of an ‘awk’ one-liner, but found it rather surprisingly difficult. Here’s the magic tickle required:

x="foo"
awk '{ print "'"$x"'" }'

That’s a ” followed by ‘ and then another “.

For the curious, the actual script was a one-liner for dumping out Mac OS X application version information:

for x in /Applications/*.app 
do mdls $x | awk -F \" '/kMDItemVersion/ { print "'"$(basename $x)"'", $2 }'
done

cheers.

From DTD to Rails Migrations

March 7th, 2007 by aaronharnly

In the category of tools that I want, but better not make right now, lest it turn into a “paroxysm of generalization”:

I have a DTD, describing a bunch of entities, their relationships, and their attributes. I’m going to push data from a set of XML files (adhering to said DTD) into a Ruby-on-Rails savvy database. Wouldn’t be nice to have a simple tool that, in the most general way possible, would, given that DTD:

  1. Issue a series of ’script/general model Foo’ commands for the various entities.

  2. Populate the Rails migration files appropriately, to manage the creation of the database tables for these entities. That would include inserting :foo_id columns for has-many and has-and-belongs-to-many relationships (though differentiating between the two might require some human supervision), and exploiting the wonderful Red Hill Foreign Key Migrations to create appropriate FK constraints.

  3. In addition / as an alternative to using the Red Hill plugin, insert the appropriate has_many / habtm declarations in the model files.

  4. And finally, make a script that can read a set of such XML files and fill the database appropriately.

Well, sounds nice to me, anyway. Put it on the someday-maybe list.