Sunday, April 22, 2007

Z-Shell command completing

Alright, I admit it. I've been using the z-shell for a few years now and have never really dug in beyond what you'd find in bash. So it finally dawned on me to figure out how to create my own completions.

Granted, I didn't dig in too far beyond the basics but still it has been extremely handy.

For any commonly used command line util get the list of commands:
grails help

Then make a line in your .zshrc (found in your home directory) that maps those commands to the grails keyword:


compctl -k '(bootstrap bug-report clean compile console create-app create-controller create-domain-class create-job create-plugin create-script create-service create-tag-lib create-test-suite generate-all generate-controller generate-views generate-webtest help init install-dojo install-plugin install-templates package package-plugin package-plugins run-app run-webtest shell test-app upgrade war)' grails


compctl can do much more powerful tricks but for me just mapping the given array of words is great.

Now I can simply type 'grails c[tab]' to list all the commands that start with 'c'

I've also made a similar array for Subversion:

compctl -k '(add blame cat checkout cleanup commit copy delete diff export help import info list log merge mkdir move propdel propedit propget proplist propset resolved revert status switch update)' svn

The best part is if you type 'svn help [tab]' you'll still get the list of keywords so you can easily get detailed help.

Good stuff.

There is a bash plugin available to help program similar completions.

Monday, April 9, 2007

Currently Reading: Groovy In Action

I'm about 75% through "Groovy In Action" and would recommend it as a great introduction to the power of scripting for Java developers. I'd also recommend reading "Programming Ruby" for a comparison to a similar, modern scripting language.

Main Thoughts:


In the corporate world I've been finding it a small uphill battle convincing talented Java developers that they should take scripting seriously. It will take a word-of-mouth campaign and probably better tools to get them on board. I suppose another way would be if someone came out with a "killer-app" written in Groovy.

Less code is less code (Or less code is like gold?)


Less code means less code to maintain and also less code to read through to understand what is going on. A main benefit of a higher level language is that the code you type has more to do with the objective and less to do with the boilerplate required to achieve that objective.

Put more succinctly: Groovy code is about an order of magnitude less than Java code performing a comparable function.

Less dependencies on Frameworks and Patterns


Getting proficient in a scripting language like Groovy will take less time than it takes to learn a new Java framework (JSF, Struts, Hibernate, etc) and may replace the need for one.

A good example of this is database persistence. In Java we have JDBC, EJB3, Hibernate, iBatis, Spring JDBC, etc. Some of these are pretty heavy frameworks that attempt to make database usage easier and less error-prone.

When you see an example of database usage from Groovy it really makes you wonder about why you'd want to jump to an external framework. The argument has often been that heavier frameworks like Hibernate take a lot of the work off your shoulders and reduce the amount of code needed. I've found that the size of the code just gets transferred to XML configuration and setup.

It seems very possible that with a language like Groovy you could have much of this power and security within the language itself, or at least with a much lighter support library.

If you could write your DAOs in Groovy I know Spring JDBC would be reduced down to a handful of technology-specific helper classes. Much of this API is resource handling, which is taken care of natively by Groovy's closures.

Design Patterns
A few years back at a conference, Dave Thomas (Pragmatic Programmers) made the comment that design patterns are a work around for deficiencies in a given programming language. It took some thinking for this idea to click but it makes so much sense. What is a design pattern other than simply boilerplate code for a concept not natively supported by the language you are using?

AOP/Visitor Pattern: Required in Java due to the lack of meta-programming that would allow interception of method calls.
Adaptor Pattern: Required in Java due to the lack of "duck typing" or "mix-ins"
Facade Pattern: Required in Java to hide usage complexity of heavy frameworks/APIs.

Side note: If you've done any tech hiring lately you'll notice how many resumes come in with "design patterns" on the technology list.

Monday, April 2, 2007

Great intro article to the power of LISP

I found this great blog entry on why any Java programmer should be interested in learning some LISP. I'm still a LISP newb but even the little I know makes understanding how to best use scripting languages like Ruby and Groovy better.

Anyway, take some time to read this:
The Nature of Lisp

Friday, March 16, 2007

Groovy on OS X and MacPorts

Update Note: This is still the case with Groovy 1.6.x and Leopard the same fix still works.

The default MacPorts install of groovy didn't work out of the box. When I ran groovy from the prompt I got a nasty java.lang.SecurityException.

The problem ended up being that my Java CLASSPATH included classes.jar.

The solution ended up clearing out the CLASSPATH system variable altogether before invoking groovy. You can do this with a command line switch but the easiest way to do it was to edit the startGroovy file (found in the /bin directory of the groovy installation). A fast way to find this is using Spotlight

I simply added CLASSPATH= as the first thing in the file:

...
##
## $Revision: 4298 $
## $Date: 2006-12-04 02:39:45 +0100 (Mo, 04 Dez 2006) $
##

CLASSPATH=

PROGNAME=`basename "$0"`
...

Groovy Process Piping: Follow-up

Thanks to some comments from those a bit more savvy on this topic I'm suggesting the following method from charlesanderson:

p=['sh','-c','ls -l | sort'].execute()
println p.text

This is mostly cross-platform (assuming CygWin) and is nicely succinct.

I like this method over using the Groovy Groosh module as suggested by Yuri Schimke if only because it doesn't require an import:

def f = gsh.find('.', '-name', '*.java', '-ls');
f.pipeTo(lines);

As always there are many ways to skin the same cat.

Monday, March 12, 2007

Groovy Process Piping

I was playing around with using Groovy as a shell scripting language. While convenient, I found that shelling out to my trusted unix commands is many times faster for file operations than handling them within Groovy.

Creating and executing a process is trivial in groovy:

p = "ls -l".execute()
println p.text
But using pipes or redirection is not allowed:

p = "ls -l | sort".execute()
println p.text
For some reason it took me awhile to understand the java.lang.Process well enough to come up with this script, which contains a helper class for piping one Unix shell command into another.
def class Pipe {
private Process p

def Pipe(cmd) {
p = cmd.execute()
p.out.close()
}

def to(cmd) {
def p2 = cmd.execute()
p2.out << p.in
p2.out.close()
p = p2
this
}

def text() {
p.text
}
}

def output = new File('output.txt')
output.delete()

output << new Pipe("grep -h -e '^.* ERROR .*' input.txt")
.to("sort")
.to("tail -n50").text()


Note 1: The Process object is in the standard JDK so with a bit of alteration, one could create the Pipe utility in straight-up Java. But in regular Java I wonder how often one needs to run a shell command?

Note 2: If you are on Windows and are using Cygwin you'll need to be aware that the Windows "sort" command clobbers the Unix version and is hardly as robust. You may need to hard code which sort you want to use: "C:\\cygwin\\bin\\sort"

Thursday, January 25, 2007

Posting from Flickr


DSC_0121.JPG
Originally uploaded by devilelephant.
Testing the ability to blog my Flickr photos directly.