Saturday, July 18, 2009

getting started with ruby 1.9

Yehuda Katz has a nice post over at his blog talking about Ruby 1.9 and what we need to do to move our community towards it.

Lots of great points are brought up, but for me, the biggest issue is just not having the time to fiddle with things, setup nice little aliases, etc. Thankfully, one of the nice guys over at Relevance has done this for us: spicy-config

On a quick side note, Chad's configs also helped me get up and running with zsh, and that's been a whole other fun trip.

You'll want to clone his repo and take a look in at his .zshrc file along with the ruby_installer and ruby_switcher files inside .zsh. All you have to do is source the files to get the functions defined, and run what you're interested in. I did set things up a little different given that I don't use the Leopard install of ruby...but if you're reading this, I assume you can see what you'd want to change if need be.

That's about it. I can now say "use_ruby_191" and it quickly switches me over, and then 'use_ruby' to jump back to 1.8.6.

Great stuff Chad, thanks!

Thursday, July 16, 2009

a couple quick git tips

The other day someone asked in #git how to fix something in the middle of an unsuccessful rebase. So, I thought I'd rebase some of my own code, reorder things so there must be a conflict, and then try to duplicate their question.

Only problem was that there was no error, and I hadn't really paid attention to which commits I reordered. Thankfully, I got a bit of help from a gent named doener.

I'm including a rather long gist showing the process. Basically, git reflog is your friend, and you should play with this at some point in a test repo like I've done here.

Note: anytime you git reset --hard be very sure and confident of what you're doing.

> mkdir undo-rebase
~ > cd !$
cd undo-rebase
~/undo-rebase > git init
Initialized empty Git repository in .git/
~/undo-rebase master > touch one
~/undo-rebase master > ga .
~/undo-rebase master > gc -m "one"
Created initial commit 3dfffad: one
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 one
~/undo-rebase master > touch two
~/undo-rebase master > ga .
~/undo-rebase master > gc -m "two"
Created commit 0c36fd9: two
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 two
~/undo-rebase master > touch three
~/undo-rebase master > ga .
~/undo-rebase master > gc -m "three"
Created commit 6c4a8e8: three
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 three
~/undo-rebase master > gl
...
commit 6c4a8e844de2809b23710fe84080187d7c6c89a6
Author: Jack Dempsey <jack.dempsey@gmail.com>
Date: Thu Jul 16 22:40:00 2009 -0400
three
commit 0c36fd9b1cf3bbc4ad29de5a62e4114465c307b3
Author: Jack Dempsey <jack.dempsey@gmail.com>
Date: Thu Jul 16 22:39:54 2009 -0400
two
commit 3dfffad2749dea6a187a32f7dd20fa4c13db452b
Author: Jack Dempsey <jack.dempsey@gmail.com>
Date: Thu Jul 16 22:39:46 2009 -0400
one
~/undo-rebase master > git rebase -i head^^
...
pick 0c36fd9 two
pick 6c4a8e8 three
# Rebase 3dfffad..6c4a8e8 onto 3dfffad
#
# Commands:
# pick = use commit
# edit = use commit, but stop for amending
# squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
~/undo-rebase master > gl
...
commit 39521f7ed570f31b778b4281072131e72ada4c82
Author: Jack Dempsey <jack.dempsey@gmail.com>
Date: Thu Jul 16 22:39:54 2009 -0400
two
commit e0014a06d12f966bf0d332a0e07cbd8c1ecff21c
Author: Jack Dempsey <jack.dempsey@gmail.com>
Date: Thu Jul 16 22:40:00 2009 -0400
three
commit 3dfffad2749dea6a187a32f7dd20fa4c13db452b
Author: Jack Dempsey <jack.dempsey@gmail.com>
Date: Thu Jul 16 22:39:46 2009 -0400
one
~/undo-rebase master > ZOMG wait wait wait
~/undo-rebase master > git reflog show master@{1}
6c4a8e8... master@{1}: commit: three
0c36fd9... master@{2}: commit: two
3dfffad... master@{3}: commit (initial): one
~/undo-rebase master > git reset 6c4a8e8 --hard
HEAD is now at 6c4a8e8 three
commit 6c4a8e844de2809b23710fe84080187d7c6c89a6
Author: Jack Dempsey <jack.dempsey@gmail.com>
Date: Thu Jul 16 22:40:00 2009 -0400
three
commit 0c36fd9b1cf3bbc4ad29de5a62e4114465c307b3
Author: Jack Dempsey <jack.dempsey@gmail.com>
Date: Thu Jul 16 22:39:54 2009 -0400
two
commit 3dfffad2749dea6a187a32f7dd20fa4c13db452b
Author: Jack Dempsey <jack.dempsey@gmail.com>
Date: Thu Jul 16 22:39:46 2009 -0400
one
Voila!
view raw gistfile1.sh hosted with ❤ by GitHub

Thursday, July 2, 2009

Opening your mind with Clojure

I know, I know, clever title, right? It's true though--I've taken the last week or so to take a stab at learning Clojure. I've played with functional languages before, but unfortunately "play" is about as far as I've gotten. This time it was different. I actually made it all the way through Programming Clojure (Pragmatic Programmers), which is saying something (I'm king of "Oh, I'll buy THAT book too!" and never finishing it...). There are a variety of reasons I'm really enjoying Clojure, but for now I'd like to offer some tips in getting set up.

Getting the Source



Rich Hickey is the guy behind Clojure. I'd call him a mad genius, except he seems pretty nice and "happy genius" doesn't really work...Anyway, he's recently agreed to move the project to github, and you can find the two main sources you'll want in his account there. Using the wonderfully helpful github gem you can clone things down with


gh clone richhickey/clojure
gh clone richhickey/clojure-contrib


At this point I'm assuming you've got java installed and working, which may be a big assumption, but I don't have the heart to tackle that mountain today.

So, get into the source and start compiling:


cd clojure
ant


If all goes well, you should have some nice jars all sparkling and ready for use. Now for contrib:


cd ../clojure-contrib
git checkout 3073f0dc0614cb8c95f2debd0b7e6a75c1736ece ***
ant -Dclojure.jar=../clojure/clojure.jar


*** At this point in time, you need this revision to compile against clojure 1.0. I imagine this will change over time, but if you have any problems with compilation, a good place to check is the #clojure channel.

You need to pass in that -D flag so we can use the clojure.jar in compiling clojure-contrib. Once this is done you'll want to put the jars into a common place where java can load them up. I've created an /opt/jars directory on my system, and so I'll drop them into here.

Now, you'll want to make sure the CLASSPATH variable is setup correctly, and it took me a while to do this the first time, so here's a hint:

# inside .bash_login
for i in `ls /opt/jars/*.jar`
do
CLASSPATH=${CLASSPATH}:${i}
done
# you can see this works by inspecting your environment
jack@localhost ~/git/clojure-contrib (no branch) $ printenv | grep -i classpath
CLASSPATH=/Users/jack/Library/Java:/Users/jack/src/vimclojure-2.1.1/src/com/martiansoftware/nailgun:/opt/jars/clojure-contrib.jar:/opt/jars/clojure-sources.jar:/opt/jars/clojure.jar:/opt/jars/commons-codec-1.3.jar:/opt/jars/commons-fileupload-1.2.1.jar:/opt/jars/commons-io-1.4.jar:/opt/jars/compojure.jar:/opt/jars/grizzly-http-servlet-1.9.10.jar:/opt/jars/grizzly-http-webserver-1.9.10.jar:/opt/jars/jetty-6.1.15.jar:/opt/jars/jetty-util-6.1.15.jar:/opt/jars/servlet-api-2.5-20081211.jar
view raw gistfile1.txt hosted with ❤ by GitHub


I think newer versions of java will just let you specify the main directory name. This is for java 1.5 which I somehow seem to still be running.

Almost there!

Setting up a clj file



I've blatantly stolen this file from Chouser, an ever present and extremely helpful soul found in #clojure (he's like Illari of #git for those who frequent that channel...if I ever get rich, a fat check is in their future).

This is what the clj file looks like:

#!/bin/bash
repo="$HOME/git/clojure/"
ext_dirs="/usr/share/java:/opt/jars"
library_path="/usr/lib/java:$HOME/.clojure/libs"
java_opts="-server -Xbootclasspath/a:clojure.jar -Djava.ext.dirs=$ext_dirs -Djava.library.path=$library_path"
if [ $(basename $0) = clj ]; then
branch=""
else
branch=branches/${0#*clj-}
fi
export CLASSPATH="$repo/$branch/clojure.jar:$CLASSPATH"
repl="-r"
while true; do
case $1 in
--) shift; break ;;
-cp) export CLASSPATH="$2:$CLASSPATH"; shift 2;;
-D*) export java_opts="$java_opts $1"; shift ;;
-X*) export java_opts="$java_opts $1"; shift ;;
-i) repl=""; break ;;
-e) repl=""; break ;;
*) break ;;
esac
done
exec rlwrap --remember --file ~/.clj_completions --complete-filenames \
--history-filename ~/.clojure/history \
--break-chars "\"\\'(){}[],^%$#@;:|" \
${JAVA:-java} $java_opts clojure.main \
-i $HOME/.clojure/repl-init.clj $repl "$@"
view raw gistfile1.txt hosted with ❤ by GitHub


If you're on OS X you'll want to install rlwrap:


sudo port install rlwrap


You'll also want an init file to help load up some useful functions like 'show' into your REPL. Create a file named "repl-init.clj" and put something like this inside:


(set! *print-length* 103)
(set! *print-level* 15)
(use '[clojure.contrib.repl-utils :only [source show]])
(use '[clojure.contrib.stacktrace :only [e]])


This should be executed by your clj script on startup, and setup things automatically for you.

Wrap-up



So that's about it for now. I'm having a great time so far, and honestly the hardest parts are getting your environment setup and keeping it up to date. If you're used to java development then this should be a breeze. Having been away from it for years, it took me a while, and hopefully this will save others that same pain.

Thanks to Paul Barry and Aaron Bedra for getting me interested in Clojure at Ruby Nation, and of course Rich et al for all the time and energy put into developing this great new language.

A few links



clojure.blip.tv - Rich gives some great presentations, and many of them are captured here.
clojure.org - Lots of great documentation here
#clojure on irc.freenode.net - over 100 clojurists and clojuristas. Very helpful and friendly.