X-Combinator

Avatar

making the human scalable

git-style-binaries screencast

Just released: git-style-binaries ruby gem. Checkout the README on github.

Checkout the screencast.

gsb-screencast1.png

adding macruby to multiruby versions

Modified from Rob Seaman’s post.

multiruby is a great way to make sure your ruby code runs on the multitude of ruby versions (it’s part of ZenTest). It doesn’t install macruby by default. Here are instructions on how to set it up.

Since I installed macruby from the package installer my macruby files are in /Library/Frameworks/MacRuby.framework/Versions/0.4/. If your macruby files are somewhere else, adjust accordingly.

First make sure you already have multiruby setup for other versions (don’t proceed if this doesn’t work):

multiruby_setup the_usual

One problem I had with the above command was that I had RUBYOPT set in my .profile. This was calling each of these ruby versions with RUBYOPT=rubygems when trying to install. This won’t work because rubygems is one of the things you’re trying to install. Make sure you unset this variable etc. before trying to setup multiruby.

ln -s /Library/Frameworks/MacRuby.framework/Versions/0.4/usr ~/.multiruby/install/macruby-0.0.4
sudo ln -s ~/.multiruby/install/macruby-0.0.4/bin/macruby ~/.multiruby/install/macruby-0.0.4/bin/ruby
sudo ln -s ~/.multiruby/install/macruby-0.0.4/bin/macgem ~/.multiruby/install/macruby-0.0.4/bin/gem
touch ~/.multiruby/versions/macruby-0.0.4.tar.gz # fake-out

Now try:

multiruby -e "p 1+1"

tweet twitter util - cli feedback on tweet length

One of the nice things about the Twitter web-interface is that it gives you feedback on the number of characters you’ve typed so far.twitter-warning.png

Since I use the command-line twitter gem (by John Nunemaker) I miss out on this feature and find myself using echo and wc to make sure I’m not over the limit.

To fix this problem, I’ve written a small, immediate-feedback utility called tweet. It shows you the number of characters typed so far and colorizes them accordingly.

Screenshots:

warning:
tweet-warning.png

over:
tweet-overage.png

Just download this script and save it as tweet somewhere in your $PATH

temporarily undo commit(s) on a remote server

I do not claim to be a wiz at git, and I do not ensure what I am writing about, but it seemed to work for me, and I appreciate any comments.

My goal was to temporarily revert one or many commits that I had pushed to the remote server.

http://cheat.errtheblog.com/s/git — specifically the “Fix mistakes / Undo” section was helpful.

What I found:

git revert -n <sha>

#run this for each commit you would like to “undo”

(the -n makes it so that you are not actually creating a commit, but staging the reverse of the changes made by your <sha> commit in your index. git status will show you this)

git ci -a # apply your revision
git push #origin to master (these steps effectively created one commit that was the product of reversing all the commits you picked in the git revert -n step)

now your index looks like:

  • <sha1>… revision of <commit…s>
  • <sha2>… commit4
  • <sha3>… commit3
  • now, lets say, the time has come to reapply your commits. Because you didn’t just do

    git reset --hard &lt;commit3&gt;

    or something like that, all you have to do is git reset –hard <sha1> which will “undo your undo”

    then

    git push #origin master

    again and you are back to where you were.

    runaway process… on a mac

    wresting with the command line, and some cool cli programs I learned on the way

    I want desperately to know how to detach a process from one terminal, and re-attach it to another, without using screen from the get-go. The more I read about it, the more I figure that the answer (you can’t) probably has more to do with my lack of understanding of how processes and terminals work. I read a great post here that introduced me to disown -h (careful) and nohup, some really great bash builtins. I thought, ok, lets try it. This is where I got stuck.

    I tried

    while true; do sleep 10; done &amp;
    disown -h %1
    exit

    The disown builtin handles a problem with background processes: From the bash man page (and also the above blog)

    The shell exits by default upon receipt of a SIGHUP

    therefore killing your process you ‘thought’ you put in the background, and then logged out to go home for the night. Disown tells the jobspec not to accept a SIGHUP, and the -h switch tells it to remain in the jobs table. I thought, cool, maybe if it stays in the the jobs table, I could also transfer it to another jobs table of another tty. (no, you can’t…)
    but now I had a process on my hands that wasn’t attached to a terminal, and would just run forever unless I rebooted.

    The while loop itself didn’t have a process ID, which is interesting, and because of the nature of while, the sleep commands PID kept changing, so a normal ps aux | grep slee[p] | awk ‘{print $2}’ | xargs kill -9 wasn’t working. (This post is loosing topic fast, but the slee[p] in the above command was a cool trick I learned so that I didn’t need a grep -v grep in there).

    I *did* find that I could use ps to figure out the ppid (parent process ID) and just kill -9 that, but I was also interested in knowing for sure that it wasn’t in charge of doing something else important. A little digging around, and I came across the UNIX utility pstree which of course didn’t come on my mac, but I quickly figured out that it could be installed with

    sudo port install pstree

    Yesterday, I had done a similar thing with the UNIX command watch, which also nicely installed using port
    And, for those who don’t know, the UNIX command watch is a great poller utility, that will display the first screen’s worth of output of any command, and update it on a regular basis.

    I used ps | grep to find the ppid of the sleep process, then ran this command:

    watch "pstree $PPID"

    This was way cool, as every ten seconds, I watched as the PID of sleep (the child process of this bash process I had just found) changed.

    Take away:

    sudo port install watch
    sudo port install pstree

    starting screen as a login shell

    I realized a while ago that I wanted to invoke my shell as a login shell when starting screen. This of course gives me immediate access to things in my .profile like aliases, etc.

    shell -bash

    Everywhere I read said to put that in your .screenrc file. On my Mac, OS X 10.5, however it seemed to have the (extremely) unwanted circumstance of changing my cwd whenever I started screen to my $HOME folder.

    I was able to do some testing my remoting into a *fairly* vanilla fedora box and running the command:

    cd /; screen -s -bash

    This started bash as a login shell

    shopt login_shell #=&gt; login_shell    	on

    but did not change my cwd.

    I tried moving my .profile file to see if it was the culprit.

    I finally came up with this hackish solution.

    create file

    screen_shell

    and place in it the line

    $SHELL -l

    I knew from other testing that

    shell 'bash -l'

    didn’t work, course, now, having remembered that I had a similar experience with vi… I wonder if

    shell bash\ -l

    would work… (nope…)

    so, I then changed my .screenrc file to read

    shell /Users/bhenderson/.screen_shell

    made sure that I did a

    chmod u+x ~/.screen_shell

    and off I went.

    If anyone would like to add to my understanding of what was going on, or a better solution, please feel free to comment. thanks.

    rsync vs. cp

    rsync -a /path/to/bar/ /path/to/foo/  # =&gt; /path/to/foo/[contents of bar]
    rsync -a /path/to/bar /path/to/foo/   # =&gt; /path/to/foo/bar/[contents of bar]
     
    cp -a /path/to/bar/ /path/to/foo/     # =&gt; /path/to/foo/bar
    cp -a /path/to/bar /path/to/foo/      # =&gt; /path/to/foo/bar

    why can’t cp have the same source behavior as rsync?

    btw, I found the solution on this blog:

    mkdir target_directory
    cd source_directory
    cp -a . target_directory

    (on the blog, the author does cp -ap, but that looks redundant according to the man page)

    what does this return? or ‘why i love ruby’

    def x
      5
    end
     
    if false
      x = 3
    end
     
    puts x # => ?

    Ruby’s #each_with_index for Erlang

    Ruby has a great method for enumerations called #each_with_index. It’s a handy way to iterate over a list of elements and and know where you’re at while doing it.

    Erlang has a group of highly optimized list operations in the lists module (Try erl -man lists to see them all). We’re going to be using those to build our Erlang version of #each_with_index.

    There are two methods from list we’re going to use: lists:seq and lists:zip. lists:seq simply returns a list of integers between a given range. For instance:

    1> Seq = lists:seq(0, 9).
    [0,1,2,3,4,5,6,7,8,9]

    lists:zip takes two lists (of equal length) and returns a list of tuples. Like so:

    2> lists:zip([a,b,c], [1,2,3]).
    [{a,1},{b,2},{c,3}]

    The last thing we need is a list comprehension, which is similar to each with a block in Ruby. For instance, in Ruby:

    >> [:a, :b, :c].each { |element| puts element }
    a
    b
    c
    => [:a, :b, :c]

    In Erlang we would do the following:

    3> [io:format("~p~n", [Element])  Element <- [a,b,c]].
    a
    b
    c
    [ok,ok,ok]

    There is one difference here: the Erlang list comprehension returns a new list which is the value of each call to io:format. In this way an Erlang list comprehension is closer to Ruby’s #collect rather than #each.

    We now have all the pieces to build our Erlang version of #each_with_index.

    4> EachWithIndex = fun(L, X) -> [
      X(Element, Index)  
      {Element, Index} <- lists:zip(L, lists:seq(1, length(L)))
       ] end.

    Whats going on here?

    lists:zip(L, lists:seq(1, length(L)))

    creates a list of tuples with each tuple containing an element of L and a companion integer.

    [X(Element, Index)  
      {Element, Index} <- lists:zip(L, lists:seq(1, length(L)))]

    tells us to take that list of tuples and do a list comprehension on each of the elements, calling fun X in turn.

    EachWithIndex = fun(L, X) -> ... end.

    creates a fun (think lambda) and assigns it to EachWithIndex. You could just as easily create this as a regular function in a .erl file somewhere.

    Now we can call our new EachWithIndex function by passing in a list and a fun:

    5> EachWithIndex([a,b,c,d,e], fun(Element, Index) -> io:format("~p at ~p~n", [Element, Index]) end).
    a at 1
    b at 2
    c at 3
    d at 4
    e at 5
    [ok,ok,ok,ok,ok]

    PoolParty s3fs Plugin

    Goal

    A new plugin install and mount s3fs volume on an instance using PoolParty.

    Getting it

    git clone git://github.com/jashmenn/poolparty-s3fs-plugin.git

    Usage

    NOTICE You must have already created your S3 bucket. This plugin will not
    create it for you.

    cloud(:app)
      ...
      s3fs(:bucket => "my-fun-bucket")
      ...
    end

    This will be mounted at /mnt/my-fun-bucket
    You can mount multiple buckets and/or change the mount point:

    s3fs do
      bucket "my-fun-bucket"
      bucket "my-other-bucket", "/mnt/a-disk"
    end

    References:

    PoolParty MRTG Plugin

    I’ve created a PoolParty plugin that makes it dead-simple to install GitHub Repo is here.

    or git clone git://github.com/jashmenn/poolparty-mrtg-plugin.git

    Usage:

    Declare mrtg in your cloud block

    mrtg do
       monitor :cpu, :uptime, :memory, :open_files, :processes, :apache, :network_interfaces
    end

    picture-11.png

    Getting Started with PoolParty and EC2

    Today I gave a presentation and workshop titled “Getting Started with PoolParty and EC2″. The goal was to 1) be an introduction to the myriad of terms used in Amazon’s cloud computing infrastructure and to 2) be a practical introduction to PoolParty configuration and provisioning.

    Posted below are the slides. The slides alone certainly are not enough for a complete introduction to PoolParty. However, I hope they have some information that is helpful to beginners.

    Check out the PoolParty wiki for more documentation.

    Whatsmyip from the Command Line

    Nice little one liner to obtain your WAN IP address.

     
    curl http://www.whatismyip.com/automation/n09230945.asp ; echo

    Then alias that badboy E.g.:

     
    alias whatsmyip='curl http://www.whatismyip.com/automation/n09230945.asp ; echo'

    Happy day.

    cp a symlink to multiple directories

    Today I wanted to copy a symlink to many different directories. So I tried the following:

    for f in `find . -regex ''.*cp.*snippets''` ; do cp bbb.html $f/ ; done

    Which returned:

    cp: cannot stat `bbb.html': No such file or directory
    

    bbb.html is a symlink and the default behavior of cp (I think) is to try and copy the actual file, which didn’t exist from the current directory. So just adding the -R made cp copy it as a symlink with the final command being:

    for f in `find . -regex ''.*cp.*snippets''` ; do cp -R bbb.html $f/ ; done

    quick(er) way to symlink your `pwd`

    I learned the other day about a neat shortcut for tilde expansion in bash.

    $ ls ~-/

    The neat thing about this expansion is that it does tab completion. What this lead me to discover is that you can also do ~N, where n is a number refering to your directory stack. (the bash man page says you can use the command `dirs’ to view the stack, but it doesn’t seem to work for me. When you put in a 0 (zero), it is the current working dir.  Combined with tab completion, this gave me a great way for creating symlinks. Before, I had to do something like

    $ ls `pwd`/

    Which does do tab completion. But if you want to save a whopping 3 key strokes!, you can do something like this:

    $ pwd
     
    /Users/bhenderson/programming/ruby/guides.rubyonrails.org
     
    $ ln -s ~0/index.html ~/Sites/ruby_guides
     
    $ ls -l !:$
     
    ls -l ~/Sites/ruby_guides
     
    lrwxr-xr-x  1 bhenderson  staff  68 Jan 12 08:47 /Users/bhenderson/Sites/ruby_guides -&gt; /Users/bhenderson/programming/ruby/guides.rubyonrails.org/index.html
     
    $

    Guide spidered from here.

    renaming (lots of) files in bash

    I found this method the other day. Unfortunately, I forget where.

    $ for f in `ls -1 | grep string`; do mv $f ${f/string/replace};done

    I’d like to find a method of using the bash command `find’, but this is pretty clean, and I don’t yet know how to manipulate the `{}’ in find -exec {} \;

    great site for explaining bash variable manipulation.

    fixing do_mysql hanging or install problems on mac os x

    Just a quick tip:

    If you’re having trouble getting do_mysql to install on Mac OS X. Try the following:

    $ locate mysql_config
    /usr/local/mysql/bin/mysql_config
    

    The directory /usr/local/mysql above is your mysql directory. Then try to install do_mysql with the following command (split for readability):

    $ gem install do_mysql -- \
       --with-mysql-dir="/usr/local/mysql/" \
       --with-mysql-config="/usr/local/mysql/bin/mysql_config"
    

    This solution was found here. I experienced the problem while trying to get merb to run with datamapper on mysql.

    sake task for remote git repo init

    sake advantages

    sake is a tool for system-wide rake tasks. It was created by Chris Wanstrath and is now maintained by postmodern. It provides a handy way to distribute generally-useful rake tasks. The advantage of sake over, say, a script in ~/bin is that 1) you have a predictable interface and 2) its easy to distribute tasks with sake -i http://any-url (in theory).

    Examples

    Ben Schwarz has written a great sake task for installing a ssh-public-key on a remote server. You can install it with sake -i http://github.com/benschwarz/sake-tasks/tree/master%2Fssh%2Fssh.sake?raw=true . (If you haven’t seen highline before, check it out. It’s a nice abstraction and clean alternative to using gets and puts.)

    A sake task for installing remote git repos

    Based on Ben’s task I’ve created a task for installing remote git repos.

    The above task will do two things:

        Create the bare repository on a foreign server
        Optionally create a local working copy

    There’s a bug in the above authentication code, did you catch it? For authentication, it will use your ssh keys if it finds it otherwise it will ask you for a password. However, if your ssh keys aren’t valid then it simply fails. Ideally it would ask you for a password and retry in this case.

    I’m not too concerned about this however; if you’re creating a git repo remotely, you probably want to clone it and you also probably have your ssh keys setup to do so. (I probably shouldn’t be checking for a password at all.)

    sake disadvantages

    I believe sake is a great idea, but there is some rough edges in the current implementation.

    Current Gem has a bug

    Today, if you gem install sake there is a bug such that sake wont even run. Your best bet is to clone drnic’s repo sake >= 1.0.16 and install from there.

    My guess is that this is because sake’s creator recently put out a request for someone to take over the project and the person who took it over hasn’t upgraded the rubyforge gem.

    Task installation

    Another bug that seems to be specific to this version of sake, when I run sake -i the task names and namespaces are created but the ~/.sake file contains no code.

    Again, this just seems to be a minor bug with the current version and as such I see it as temporary. I’m planning on working on a patch on for this, though I’m not sure I’ll fix it before someone else.

    Task development

    The built-in way to do sake task development is to write a little bit, then sake -i your file, then write a little bit more etc. This gets old fast. Because of that drnic has written a great project for sake task development. In that project you run sake testrun taskname.

    drnic’s project is handy and makes sake task development a snap. However, I think this fact could slow the adoption of sake; it’s a barrier to entry if you have to install a second project just to develop the first.

    Even so …

    I still think that the idea of sake is solid. There is definitely a need for easily distributable, reusable, system-wide rake tasks. Despite its current shortcomings, sake is definitely worth a look.

    Why Do Cells Have DNA?

    In order for a system to reproduce itself, it seems necessary for it to hold an encoded form of itself somehow. This idea, and the inevitability of the existence of DNA-like structures within living cells, is well-illustrated using computer code.

    [Read more]

    run multiple rake tasks simultaneously

    Here’s a quick and simple tip for using threads and Rakefiles:

    task :one do
      puts "start one"
      sleep 10 * rand
      puts "one done"
    end
     
    task :two do
      puts "start two"
      sleep 10 * rand
      puts "two done"
    end
     
    task :three do
      puts "start three"
      sleep 10 * rand
      puts "three done"
    end
     
    desc "Submit all feed to amazon for SITE"
    task :do_all do
      threads = []
      %w{one two three}.each do |number|
        threads << Thread.new(number) do |my_number|
          Rake::Task[my_number].invoke
        end
      end
      threads.each { |thread| thread.join } 
    end

    Running it gives something like the following:

    $ rake do_all
    start one
    start two
    start three
    three done
    one done
    two done

    Feature Creep



    feature-creep, originally uploaded by opcprogrammers.

    Apparently my canon scanner-driver has a built-in music player.

    visualize state_machine’s with graphviz

    The guys at Plugin-a-week have written a nice ActiveRecord state machine gem called state_machine.

    One of the great things about state machines is that they often can be visualized. To that end I’ve written a small utility that will load a class that uses state_machine and produce dot output which you can use with graphviz.

    This gem is currently used by the spree shopping cart. Let’s look at an example of how this can be used to visualize the Order object in this project:

    Save the gist below to visualize.rb and chmod +x visualize.rb. The arguments are 1) the path to RAILS_ROOT of the project using state_machine and 2) the class you want to visualize. Try visualize.rb –help to see all the options.


    ruby visualize.rb . Order | dot -Tsvg -Grankdir=LR > graph.svg

    Gives us the following image:

    Spree State Machine

    Download the raw code (Requires ‘trollop’ gem).

    Slides from Apriori.rb LA Ruby Presentation

    Last night I gave a talk on my new gem Apriori.rb at the LA Ruby Meetup. Here are the slides from that presentation. Coby Randquist from Confreaks recorded the talk on his MacBookPro. I’ll see if I can get a copy and post it up here in the next couple of weeks.

    Apriori.rb - a gem to find regularities in buying behavior (frequent itemsets)

    What it is

    Apriori.rb is a library to efficiently find item association rules within large sets of transactions. The goal is to find regularities in buying behavior. This library provides a thin ruby wrapper around Christian Borgelt’s C implementation of this algorithm.

    Why use it?

    Finding items that are frequently purchased together can be very useful in learning how to position products in your store or website. If you find that customers who buy product a also buy product b then you know to put a and b close together, thus increasing revenue.

    An association rule is something like:

    If a customer buys wine he buys cheese too.

    How to use it

      require 'apriori'
     
      transactions = [  %w{beer doritos},
                        %w{apple cheese}, 
                        %w{beer doritos}, 
                        %w{apple cheese}, 
                        %w{apple cheese}, 
                        %w{apple doritos} ]
     
      rules = Apriori.find_association_rules(transactions,
                                :min_items => 2,
                                :max_items => 5,
                                :min_support => 1, 
                                :max_support => 100, 
                                :min_confidence => 20)
     
      puts rules.join("\n")
     
      # Results: 
      # beer -> doritos (33.3/2, 100.0)
      # doritos -> beer (50.0/3, 66.7)
      # doritos -> apple (50.0/3, 33.3)
      # apple -> doritos (66.7/4, 25.0)
      # cheese -> apple (50.0/3, 100.0)
      # apple -> cheese (66.7/4, 75.0)
     
      # NOTE:
      # beer -> doritos (33.3/2, 100.0)
      # means: 
      # * beer appears in 33.3% (2 total) of the transactions (the support)
      # * beer implies doritos 100% of the time (the confidence)

    More information and code samples available in the documentation (rdoc).

    How to get it

    Install the gem:

    gem install apriori

    Get the source:

    git clone git://github.com/jashmenn/apriori.git

    Or view the source on github.

    requirements

    requires rubygems >= 1.2.0 . This is a requirement that hopefully will be changed in the future. But for now, know that if you don’t have rubygems >= 1.2.0 it will fail silently on the install. To update your rubygems version do:


    gem update --system

    a simple script to organize downloads

    Description

    Organize all files in a given folder by date. This is commonly used to organize a “Downloads” folder. Currently this script will only move files more than 24 hours old. This is to protect against moving a file as it is downloaded.

    Motivation

    I love SafariStand. One of the features that I love is the sort-downloads-by-date feature. Now that I have moved to Firefox I really miss this feature. I been unable to find a good extension that will sort my downloads in a similar way. This script was written as an simple way to fill that gap.

    Setup

    I keep a ~/bin directory where I keep simple scripts such as this. Then setup a crontab such as the following:

    */10 * * * * /usr/local/bin/ruby /Users/nathan/bin/organize_folder_by_date.rb /Users/nathan/Desktop/Downloads
    

    Acquiring

    It is available on github: here (raw).
    or

    git clone git://github.com/jashmenn/download_sort.git
    

    use Quick Look as a Firefox application handler

    I really dislike getting screen-shots in the format of power-point files. Thankfully, 10.5’s Quick Look can help me preview power-point files. What I needed was a way to have Firefox automatically Quick Look all power-point files that I downloaded. Here’s how to do it:

    Open up Script Editor and paste this:

    on open filelist
    	repeat with i in filelist
    		do shell script "qlmanage -p '" & POSIX path of i & "' >& /dev/null &"
    	end repeat
    end open

    picture-2.png

    File > Save As…. Choose “Application” and save it somewhere it won’t move. I choose /Applications/ql.app.

    Now simply choose ql.app next time you download a power-point file or set it up in Firefox’s Preferences > Applications.

    picture-3.png

    qlmanage is the command-line tool to open files in Quick Look. By using AppleScript you are able to create this thin “application” that Firefox will trust and give a downloaded file (As opposed to a shell script, which Firefox will not let you choose as a file handler).

    lftp has an option mirror:order

    We’ve been using lftp for years here. It’s stable and has a volume of options. I just found out today that lftp has an option to set the order in which files are uploaded if you are using the mirror command. You can set it like so:

    set mirror:order ‘*.jpg *.gif *.png *.js *.css * */’

    This will send first jpg, then gif, then png files etc. This is very handy if you are mirroring an entire website and you want the images to go live before the html does.

    String interpolation is faster than printf in Ruby

    Just wanted to make a note, string interpolation is faster than printf in Ruby. Example:

    $ irb
    >> require 'benchmark'
    => true
    >> Benchmark.measure { 100000.times {
      "%s" % ["hello world"] } }.total
    => 0.21
    >> Benchmark.measure { 100000.times {
      "#{'hello world'}"} }.total
    => 0.04

    ActiveRecord from_xml (and from_json) part 2

    This post is an upgrade to the previous post about the unmarshalling of XML and JSON strings into rails objects, with arbitrarily deep object associations. As you may know if you are reading this, there doesn’t seem to be a way in rails to reverse to_xml and to_json when associations are included.

    Example usage:

    xml = firm.to_xml :include => [ :account, :clients ]  
    firm = Firm.from_xml xml

    firm.account and firm.clients will behave as intended (by default there does not seem to be a direct way in rails to unmarshall them.)

    Here’s how to get from_xml and from_json defined for your ActiveRecord classes:

    Create a file lib/extensions.rb with the following code:

    module ActiveRecord
      class Base
     
        def self.from_hash( hash )
          h = hash.dup
          h.each do |key,value|
            case value.class.to_s
            when 'Array'
              h[key].map! { |e| reflect_on_association(
                 key.to_sym ).klass.from_hash e }
            when /\AHash(WithIndifferentAccess)?\Z/
              h[key] = reflect_on_association(
                 key.to_sym ).klass.from_hash value
            end
          end
          new h
        end
     
        def self.from_json( json )
          from_hash safe_json_decode( json )
        end
     
        # The xml has a surrounding class tag (e.g. ship-to),
        # but the hash has no counterpart (e.g. 'ship_to' => {} )
        def self.from_xml( xml )
          from_hash begin
            Hash.from_xml(xml)[to_s.demodulize.underscore]
          rescue ; {} end
        end
     
      end # class Base
    end # module ActiveRecord
     
    ### Global functions ###
     
    # JSON.decode, or return {} if anything goes wrong.
    def safe_json_decode( json )
      return {} if !json
      begin
        ActiveSupport::JSON.decode json
      rescue ; {} end
    end

    At the bottom of config/environments.rb, insert the line:

    require 'lib/extensions' # custom class extensions

    You can name the “extensions.rb” file anything else you want; just update the environments.rb file accordingly.

    This is an improvement over the previous post, in that it can work even when your associations use the :class_name parameter, you’re not editing the vendor/rails files directly, and it can deal with hashes of the rails class HashWithIndifferentAccess.

    Mac OS X color showing ESC[whatever for git-diff colors (and more)

    Since my upgrade to OS X 10.5 I have been having a terrible time getting colors to work with git.

    Originally I was using OS X 10.5.4, git version 1.5.3.1, and iTerm or Terminal.app. $TERM=xterm or xterm-color. I have color with PS1, ls, vim and most git tasks. However, git diff (or git show) always screws up the diff by showing the ESC[ characters instead of colors. For instance:

      [nathan@nate ~/s3]$ git show 67d254ec17f
      ESC[33mcommit 67d254ec17fdc507765ddee1feb2a14e5896e79fESC[m
    

    I searched and searched wasn’t able to figure out how to fix this. It was suggested on the github forum that I upgrade to git 1.5.6.4. Unfortunately not only did it not fix the color in git diff, it broke the color in git status which was working previously.

    After about a week of poking around on and off I discovered that the problem was not git, but my GIT_PAGER which is more. If I tried GIT_PAGER=cat git-diff then the color output just fine. less and more use the same environment variable LESS (man less for details). And less was outputting the colors as raw escape codes.

    man less shows that the option -R is defined as follows:

           -R or --RAW-CONTROL-CHARS
                  Like  -r,  but  only  ANSI "color" escape
                  sequences are output in "raw" form.
    

    That would do it.

    After perusing the man page for a while I settled on adding this to my
    ~/.profile:

      export LESS="-erX"
    

    At the end of the day, this tip is really about less and how it interprets colors and probably has little to do with git. Even so, I only found this odd behavior while using git. Hopefully this post will help someone who is having similar issues.

    As a side note, below is an example of how to configure your colors for git-diff and other commands.

    [user]
        name = Your Name
        email = y...@yours.com
    [color]
        branch = auto
        status = auto
        diff = auto
    [color "diff"]
        meta = yellow
        frag = cyan
        old = red
        new = green
    [color "branch"]
        current = yellow reverse
        local = yellow
        remote = green
    [color "status"]
        added = yellow
        changed = green
        untracked = cyan
    [alias]
        st = status
        ci = commit
        co = checkout
        br = branch
    

    Next,