• Spellcheck your files with Aspell and Rake

    We recently redid our website. The new site included a new design and much more content explaining what we do. We wanted a quick way to check over everything and make sure we didn't miss any spelling errors or typos. First I started looking for a web service that could scan the site for spelling errors. I found spellr.us, which is nice but would only catch errors once they were live. It also can't scan all of the pages which require being logged in.

    I was pairing with Avdi who thought we should just run Aspell, which worked out great. We were originally trying to just create a simple Emacs macro to go through all our HTML files and check them but in the end created simple Rake tasks, which makes it really easy to integrate spellcheck into CI. After Avdi figured out the commands we needed to use on each file to get the information we needed from Aspell, it was easy to just wrap the command using Rake's FileList. To keep everyone on the same setup, we created a local dictionary of words to ignore or accept and keep that checked into source control as well.

    The final solution grabs all the files you want to spell check, then runs them through Aspell with HTML filtering. We have two tasks: one that runs in interactive mode the the user can fix mistakes and one mode for CI that just fails if it finds any errors.

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on May 26th, 2009 by Dan in Development, Ruby, Tips & Tricks, Tools and tagged , , , .

  • Our Tools & Practices for Remote Collaboration

    Last week, we had Avdi, the newest addition to our team, join us in Boulder, CO. It was great to get some face-to-face time, since Avdi will primarily be working from his home in Pennsylvania while Dan and I continue to work in Boulder.

    We are excited about the benefits of having a distributed team, but we're also aware that there are a number of challenges. As a result, one of the things we worked on last week was figuring out the tools and practices we'll be using to work effectively from across the country. Luckily, both Avdi and Dan have experience working remotely which we can draw upon.

    We evaluated a number of options, but settled on the following tools and practices.

    Practices

    • Daily Standup. Every day at the same time, we all get on video chat. We cover what we did yesterday, what we're working on today, and whether or not we're blocked on anything. The goal is to keep this meeting at 15 min or less.
    • Minimize interruptions. Whenever we need to communicate with each other, we try to do so on the channel that is the least disruptive (and disrupts the fewest team members). Of course, sometimes we need to be disruptive if an issue is pressing, if someone is blocked, or if we need to have high-bandwidth communication (information, especially cues like body language, don't come across very effectively on channels like email)
    • Keep it simple. We want to use the smallest number of tools and channels that will allow us to work effectively.

    Channels and Tools

    Less
    disruptive
    More
    disruptive
    Channel Tool Properties
    Passive Updates Present.ly
    • Asynchronous
    • Not required reading
    Email Any email client (in practice, Gmail)
    • Asynchronous
    • Required reading (usually)
    • Sometimes time-sensitive, sometimes not
    IM Skype
    • Semi-synchronous (but usually synchronous)
    • Usually time-sensitive
    Voice/video chat Skype
    • Synchronous
    • High bandwidth* (especially video chat)
    • Best for meetings

    * By "high bandwidth", I don't mean that the tool itself requires a lot of TCP/IP traffic (although this is true, it doesn't really matter). What I mean is that we can communicate a lot of information between team members in a short amount of time.

    Other Tools

    • Lighthouse for issue tracking
    • GitHub for source control and our project wiki
    • RealVNC for screen sharing (essential for remote pair programming)

    This is our first attempt at finding a good set of tools and practices for remote collaboration. As time goes on, we'll undoubtedly iterate and improve upon these.

    For another perspective (with a slightly different set of tools), here is a presentation from 2008 about virtual teams.

    What tools and practices have worked (and which have not worked) for your team?

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on April 28th, 2009 by Ben in Development, Devver, Tips & Tricks, Tools.

  • Managing Amazon EC2 with your iPhone

    I wanted a quick way when out and about to easily manage our AWS EC2 instances while out and about. It hasn't happened often, but occasionally I am away from the computer and I need to reboot the instances. Perhaps I remember our developer cluster isn't being used and want to shut it down to save some money.

    I didn't find anything simple and free with a quick Google search, so in a about an hour I wrote a nice little Sinatra app that will let me view our instances, shutdown, or reboot any specific instance or all of them. The tiny framework actually turned out to be even more useful as I now have options that let us tail error logs, reboot Apache, reboot mongrel clusters, or execute any common system administration task.

    I won't be going into detail on how to build a iPhone webapp using Sinatra and iUI, because Ben already created an excellent post detailing all of those steps. In fact I used his old project as the template when I created this project. I can't begin to explain how amazingly simple it is to build an iPhone webapp using Sinatra, so if you have been thinking of a quick project I highly recommend it.

    Here are some screen shots showing the final app. (screenshot courtesy of iPhoney):

    ec2 manager home view

    ec2 manager home view.

    ec2 manager describe view

    ec2 manager describe instances view.

    ec2 manager instance view.

    ec2 manager instance view.

    This app uses the Amazon EC2 API Tools to do all the heavy lifting. So this app assumes that you already have the tools installed and working on the machine you want this app to run on. This normally involves installing the tools and setting up some environment variables like EC2_HOME, so make sure you can run ec2-describe-instances from the machine. After that you should just have to change EC2_HOME in the Sinatra app to match the path where you installed the EC2 tools.

    Let me know if you have any issues, it is quick and dirty, but I have already found it useful.

    To run the app:
    cmd> ruby -rubygems ./ec2_manager.rb

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on March 5th, 2009 by Dan in Amazon Web Services, Development, Hacking, Ruby, Tips & Tricks, Tools and tagged , , , , .

  • Installing and running git-svn on Mac OSX 10.4 Tiger

    I am shocked at how much time it took me to get git-svn working on my mac. I use MacPorts, which works well most of the time. Sometimes it has problems which makes me really wish for apt-get on OS X. apt-get normally has worked much nicer for me, but can have its issues too. I even occasionally wish for Windows and a simple install.exe which works 95% of the time out of the box. Really I wish Apple would throw some engineer support to MacPorts and make the service rock solid.

    I have had git installed and working for awhile, but preparing to switch our main project from Subversion (svn) to git, I thought I should start using git-svn. It seemed smart to use git-svn for awhile to get used to git, before a full switch so I could fall back on svn in a crunch. I decided to start using git-svn, but the first run of the git-svn command caused this error, and I had no idea how much of my night was about to be wasted...

    Can't locate SVN/Core.pm in @INC

    Searching led to a couple of webpages, but the most useful was getting git to work on OS X Tiger. It had a quick fix that might work or the long route fix. For some lucky people it is just a path problem. I checked if that was the case for me, by the following command

    PATH=/opt/local/bin:$PATH; git svn

    unfortunately for me I got the same error, OK I need to reinstall SVN with additional bindings...

    > sudo port uninstall -f subversion-perlbindings
    > sudo port install -f subversion-perlbindings

    leading to this error:

    ---> Building serf with target all
    Error: Target org.macports.build returned: shell command " cd "/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_www_serf/work/serf-0.2.0" && make all " returned error 2
    Command output: /opt/local/share/apr-1/build/libtool --silent --mode=compile /usr/bin/gcc-4.0 -O2 -I/opt/local/include -DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK -no-cpp-precomp -I. -I/opt/local/include/apr-1 -I/opt/local/include/apr-1 -c -o buckets/aggregate_buckets.lo buckets/aggregate_buckets.c && touch buckets/aggregate_buckets.lo
    libtool: compile: unable to infer tagged configuration
    libtool: compile: specify a tag with `--tag'
    make: *** [buckets/aggregate_buckets.lo] Error 1

    I spent some time searching and eventually I find the solution to the serf error. I couldn't read the blog because it wasn't in English, but I could read enough to solve my MacPorts serf install problem. I followed these few lines from the blog

    cd /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_www_serf/work/serf-0.2.0
    $ sudo ./configure --prefix=/opt/local --with-apr=/opt/local --with-apr-util=/opt/local
    $ sudo make all
    $ sudo port install serf

    Awesome, I have serf. Now what is next? Back to building svn with perl bindings, that works. Now, let's build git again since svn with perl bindings is finally installed.

    sudo port install git-core +svn

    Which fails because of p5-svn-simple

    dyld: lazy symbol binding failed: Symbol not found: _Perl_Gthr_key_ptr
    Referenced from: /usr/local/lib/libsvn_swig_perl-1.0.dylib
    Expected in: flat namespace

    dyld: Symbol not found: _Perl_Gthr_key_ptr
    Referenced from: /usr/local/lib/libsvn_swig_perl-1.0.dylib
    Expected in: flat namespace

    Error: Status 1 encountered during processing.

    OK, I need to get p5-svn-simple working. Searching leads to this thread MacPort errors related to git. Here you will find the amazingly useful comment by Orestis:

    "As mentioned move your libsvn_swig_perl* out of /usr/local/lib AND out of /usr/lib into temporary folders.

    Uninstall and reinstall subversion-perlbindings

    Install p5-svn-simple (and git-core +svn which is what lead me here)

    Move the libsvn_swig_perl files back in /usr/lib and /usr/local/lib (or else git svn won't work). 

    > cd /usr/local
    > mv ./lib/libsvn_swig_perl* ./bak/
    > sudo port install p5-svn-simple

    Sweet that works now

    > sudo port install git-core +svn
    > cd /usr/local
    > mv ./bak/libsvn_swig_perl* ./lib/

    Finally I try to run git-svn, only to see the same ERROR I had from the very beginning! I am about to lose it but decide that I should try the quick fix again to see if it is the path issue...

    PATH=/opt/local/bin:$PATH; git svn

    It works! Alright now it is just a path problem. So I open up my .bash_profile, and notice I already have that path included

    # Setting the path for MacPorts.
    export PATH=/opt/local/bin:/opt/local/sbin:/Applications/MzScheme\ v352/bin:$PATH

    But I also have an additional path added from when I originally built git from source, and it looks like I was running my old broken version of git-svn. So I just had to remove this one line from my .bash_profile

    export PATH=~/projects/git-1.5.6.1:$PATH

    and hours later and with a ton of frustration I have a fully functioning git-svn.

    Now that it is working, you can move on to learning git-svn in 5 minutes.

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on December 9th, 2008 by Dan in Development, Hacking, Misc, Tips & Tricks, Tools.

  • Revisiting additional Ruby Tools

    I have heard about new Ruby tools since I did my Ruby Tools Roundup. I am always interested in tools that can help improve our code, so I had to check some of them out. Similar to my last tools post, I will be trying out a tool and writing my general impressions along with the basic usage.

    reek


    I have to start with reek, since it has been the most requested and searched on our site since I originally wrote about tools. reek will help identify code smells, allowing you to fix up your code. Instead of looking at cyclomatic complexity or other metrics, reek looks at patterns to warn you about bad code. Reek currently detects a few code smells (Long Method, Large Class, Feature Envy, Uncommunicative Name, Long Parameter List, Utility Function, Nested Iterators, Control Couple, Duplication) but more are on the way.

    I think this project is useful but would need to be more customized before a nightly run would yield very useful results. The biggest problem I have is the signal to noise ratio seemed pretty high. Reek was warning me about "long methods" that were only 7 statements long, which just isn't something I am concerned about. The warnings on duplicate methods calls can be useful, after running reek on a few files I found a couple places where duplicate method calls were wasting time. Many of the other smells are interesting like 'Feature Envy', and 'Utility Function'. I will need to use reek more before I know if these smells are good indicators or often false positives.

    Below reek finds a utility function next_tick which is definitely a helper function that actually exists in two of our files, which probably should be moved into a helper mixin.

    def next_tick
        if(EM.reactor_running?)
          EM.next_tick do
            yield
          end
        else
          yield
        end
    end

    I am really looking forward to see how the tool progresses. If the project allows for a simple config customization to change the thresholds as well as ignore some files/smells, this could become a very useful tool to help keep a team maintain a high expectation of code quality. It would be useful to get nightly reports about any code that might not meet expectations, so a quick group code review could decide if it is an exception (which can be quickly added to the config) or if the code should be refactored and cleaned up.

    dmayer$ sudo gem install reek
    dmayer$ reek ./lib/client/client.rb
    [Utility Function] Client#next_tick doesn't depend on instance state
    [Long Method] Client#process_done has approx 7 statements
    [Duplication] Client#process_ready calls @buffer.create_reload_msg more than once
    [Long Method] Client#process_ready has approx 10 statements
    [Duplication] Client#report_system_message calls result.msg more than once
    [Feature Envy] Client#report_system_message refers to result more than self
    [Duplication] Client#send_tests calls Time.now more than once
    [Long Method] Client#send_tests has approx 24 statements
    [Feature Envy] Client#send_tests refers to tests more than self
    #check a whole directory
    dmayer$ reek ./lib/client/*

    Towelie


    Towelie helps discover duplication in Ruby code, it will help keep your code DRY. It doesn't have a nice interface at the moment and it is pretty young code. That being said, it can still be a really useful tool to help guide refactoring and code cleanup.

    ~/projects dmayer$ git clone git://github.com/gilesbowkett/towelie.git
    dmayer$ cd ~/projects/devver/
    dmayer$ irb -r ~/projects/towelie/lib/towelie.rb
    irb(main):001:0> @t = Towelie.new
    => #, @model=#>
    irb(main):002:0> @t.parse "lib/client"
    (string):24: warning: useless use of a variable in void context
    => nil
    irb(main):003:0> puts @t.duplicates
    found in:
    lib/client/test_unit_reporter.rb
    lib/client/rspec_reporter.rb
    
    def nl
    report_nl
    end
    
    ... 2 more dupes in the reporters ...
    
    found in:
    lib/client/test_unit_reporter.rb
    lib/client/rspec_reporter.rb
    
    def report(str)
    print(str.to_s)
    end
    
    found in:
    lib/client/sync_client.rb
    lib/client/rev_sync_client.rb
    lib/client/rev_client.rb
    lib/client/client.rb
    
    def quit
    send(@buffer.create_quit_msg)
    end
    
    found in:
    lib/client/sync_client.rb
    lib/client/rev_sync_client.rb
    lib/client/rev_client.rb
    lib/client/client.rb
    
    def send_quit
    send(@buffer.create_quit_msg)
    end
    
    => nil
    irb(main):004:0>

    There are currently many duplications because we are maintaining two clients while deciding what route to eventually take. We have also moved a lot of our shared client code into a mixin, and Towelie finds some methods that really should be moved there as well such as the methods "quit" and "send_quit", which is currently duped in 4 files. Towelie also points to the fact that we should refactor our reporters because they both duplicate code.

    I have always been annoyed with copied and pasted functions accidentally working its way in code, this could be a useful nightly run to keep a team DRY. Sometimes two team members implement the same functionality without even knowing a solution already exists in the code base. If you want to go a bit more in depth, check out Giles Bowkett's (creator of Towelie) How to use Towelie

    Flay


    Flay is another great tool by Ryan Davis who also works on Heckle and Flog which I covered in the past. Flay, like Towelie, helps keep your code DRY, it detects exact and similar code throughout a project. It seems to be more powerful than Towelie, as seen in this Towelie and Flay comparison. My biggest complaint is the current release has some pretty basic output that you see below. The output I got from Towelie was immediately more recognizable and useful, while Flay currently requires you to dig in a bit deeper on your own into its suggestions. An improvement is already being worked on and a verbose output mode should be in the release soon. Once better output is included I think Flay will be immediately useful out of the box even with small amounts of developer effort.

    I like that Flay has weight system, which should make it easy to set some threshold to ignore, high level weights are more likely to be worth your time and attention. One piece of code Flay tagged with a low weight was code that rescued and logged different errors thrown, which while similar actually served a purpose.

    rescue Errno::EISDIR => ed
          @stderr.puts "Error: #{ed.message}" if @stderr
          @stderr.puts "You can't pass a directory to devver only test files. Quitting." if @stderr
          send_quit
        rescue LoadError => le
          @stderr.puts "Error: #{le.message}" if @stderr
          @stderr.puts "Not all of the files can be found. Quitting." if @stderr
          send_quit
        rescue SyntaxError, NameError => se
          @stderr.puts "Error: #{se.message}" if @stderr
          @stderr.puts "This file doesn't appear to be a valid Ruby file. Quitting." if @stderr
          send_quit
    end

    Digging into the Flay results turned up some duplicate code that Towelie had missed. Since Towelie also caught a method that was duped in 4 client files that Flay missed (I was expecting Towelie's results to be a subset of what Flay found), perhaps there is room for both of the tools and learning to work with both a little bit is worth the time. After a little bit of work perhaps one of the projects will become a clearly better option. Until then I will be following both of these projects.

    sudo gem install flay
    dmayer$ flay lib/client/*.rb
    Processing lib/client/client.rb...
    Processing lib/client/mod_client.rb...
    ...
    Processing lib/client/syncer.rb...
    
    Matches found in :defn (mass = 84)
    lib/client/mod_client.rb:86
    lib/client/mod_rev_client.rb:124
    
    Matches found in :block (mass = 57)
    lib/client/client.rb:201
    lib/client/client.rb:205
    lib/client/client.rb:209
    
    ... 6 more results ...
    
    Matches found in :if (mass = 34)
    lib/client/mod_client.rb:63
    lib/client/mod_rev_client.rb:111
    
    Matches found in :defn (mass = 32)
    lib/client/mod_rev_client.rb:36
    lib/client/mod_rev_client.rb:50


    Conclusions


    That should cover it for this Ruby tools post, but I am really enjoying checking out the tools showing up in the Ruby scene. So as always let me know if I missed something, or if there is a tool you would like to see a full write up on. After some of the tools mature a little bit I will have to revisit a few of the tools which are currently in the early stages. I hope the Ruby tools scene keeps as active as it has been lately because there are some interesting projects being worked on.

    honorable mentions (things I didn't think really needed a full write up)


    • metric-fu a great gem to give quick access to a bunch of tools and metrics about your code (RCov, Saikuro, Flog, SCM Churn, and Rails Stats)
    • CruiseControl.rb when you start using all of these tools, continuous integration starts to become more important (or doing nightly runs). CruiseControl.rb is dead simple continuous integration.
    • Simian another code duplication tool, which is mentioned in 3 tools for drying your Ruby code (free for OSS, $99 for a license)
    • Ruby Tidy a tool for cleaning up HTML (I haven't used this in Ruby, but loved the Java version in my Java days)
    • Watir is an open-source library for automating web browsers. It allows you to write tests that are easy to read and maintain. It is simple and flexible.
    • Autotest, if you haven't heard of autotest, check it out, continuously run your tests every time you save a file in your project.
    • Rufus a tool that checks if code you are about to load is safe. Allows you to look for custom patterns that you don't want to run.
    • I wrote about a couple benchmarking tools last time and here is a great article / tutorial on Ruby benchmarking

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on December 3rd, 2008 by Dan in Development, Hacking, Misc, Ruby, Tools.

  • Building a iPhone web app in under 50 lines with Sinatra and iUI

    One awesome thing about the iPhone is that it can display documents very nicely, including Word, Excel, and PDF files. However, the other day I was complaining that it's not very easy to view the documents you store on your computer on your iPhone. Sure, you could email them to yourself, but then you have to search through your mail on your iPhone to find your documents. And I'm sure there is a snazzy iPhone app from the App Store to do this as well. But instead, let's build a quick web app using Sinatra and iUI.

    Here's what we'll be building (screenshot courtesy of iPhoney, which rules, by the way):

    A screenshot of the butler iPhone web app

    It doesn't look like much, but hey, it's less than 50 lines of code

    When you click on git-tutorial.pdf, you'll see the full document

    When you click on git-tutorial.pdf, you'll see this

    Sinatra is a really awesome minimalist web framework. It lets you build web applications with just a few lines of code. iUI is a collection of JavaScript, CSS, and images that lets you easily make your web sites look great on the iPhone. Using these two tools, it's really easy to build simple iPhone apps.

    To begin, install the Sinatra gem:


    > gem install sinatra

    Now, let's start with a simplest version of our app, which we'll call 'butler'. Let's make a directory for butler.


    > mkdir butler
    > cd butler
    > touch butler.rb

    Open up butler.rb in your favorite editor and type:

    Now start butler on your command line: > ruby -rubygems ./butler.rb and point your browser to http://localhost:4567 (you can use your computer's browser or the one on your iPhone - it doesn't matter. I find it's better to use the one on my computer while building the app, since it's easier to read Sinatra's debugging messages if something goes wrong). You should see a page that just says "Your files, sir." Congrats! You've made your first Sinatra app. Wasn't that easy?

    OK, let's make butler a little more useful. Sinatra will serve up any files in a subdirectory named public. Since we'll eventually be using this public directory for holding other JavaScript and CSS files as well, we'll actually put our files in ./public/files. We'll also make a link for convenience. Finally, while we're at it, let's put a few test files in there.

    > mkdir -p public/files
    > ln -s public/files files
    > echo "foo" > public/files/foo.txt
    > echo "bar" > public/files/bar.txt

    We want butler to link to each file, so let's build a little helper for that. In Sinatra, you can include helpers within a helper block. We'll also try out our helper for one file.

    Go refresh your browser to see the changes. There's no need to restart your application, because Sinatra automatically reloads changes (very cool!). You should see a link to foo.txt. Click on it, and you'll see the contents.

    Clearly, we don't want to hardcode this for just one file. Let's alter butler to look for every file within the ./files directory.

    OK, refresh your browser and you should see both foo.txt and bar.txt. This is looking pretty good, but we're not really creating valid HTML right now. We're missing html, head, and, body tags at the very least. We could add this all within our "get" handler, but that would clutter up the code.

    Instead, let's put this code into a view. Sinatra actually lets you put the view right after your other code, so you can build an entire application in one file. For simplicity, I'm going to do that for this tutorial. However, if this approach bothers you (or just messes up syntax highlighting in your editor), rest assured you can place the view code in a views directory and it would work the same way.

    Let's add the view to the end of our file, and use it in our handler. Notice that I name the view 'index' by beginning my declaration with @@ index - if I wanted a separate file, I would just put it in ./views/index.erb (you can also use Haml, if that's your cup of tea). Note I assign @links in the handler and it automatically is available in the view.

    Refreshing the browser now isn't really that exciting, since things look the same, but if you wanted, you could easily play around with the view to make things look different.

    One glaring problem is that this page isn't very usable on the iPhone itself. That's where iUI comes in. Start by downloading it (URL is in instructions below) to your butler directory, unzipping it, and copying the necessary files into your public directory.


    > mkdir iui
    > cd iui
    > wget http://iui.googlecode.com/files/iui-0.13.tar.gz
    > tar -xzvf iui-0.13.tar.gz
    > cd ..
    > mkdir public/images
    > cp iui/iui/*.png public/images
    > cp iui/iui/*.gif public/images
    > mkdir public/javascripts
    > cp iui/iui/*.js public/javascripts
    > mkdir public/stylesheets
    > cp iui/iui/*.css public/stylesheets

    To use iUI, you'll need to include the JavaScript and CSS in your view. You'll also need to add some elements to the body of your view. When you're done, the view will look like this:

    This html is probably a bit confusing, but don't worry. There are a few examples in ./iui/samples/ to learn from (and good iUI tutorials on the web). Finally, you'll want to alter the file_link helper to print out iUI code, like so:

    Note that target='_self' code. You need that to get iUI to open a link in a normal way. If you leave it off, it will use an AJAX call to load the file within the current page, which looks really funny when you try to open a binary file like a PDF.

    The final code looks like this:

    And there you have it - an iPhone web app in less than 50 lines of code, thanks to Sinatra and iUI. Now, whenever you want to view some files on your iPhone, either copy the file:

    > cp path/to/my_file ./files

    or if you prefer, link it:

    ln -s path/to/my_file ./files

    ... and then run butler

    ruby -rubygems ./butler.rb

    Figure out the IP address of your computer and simply point your iPhone browser to http://<ip>:4567

    I use butler primarily within my home network, but if you want to be able to view your files on the go, you'll need to poke a hole in your firewall. That's a bit outside the scope of this tutorial, but a quick Google search should give you some good results.

    Enjoy!

    Update: Removed an unused parameter from the code after pmccann called it to my attention.
    Update: Added -z option to tar after Peter pointed out the omission. The tar command without -z worked for me on OS X 10.5, but this is definitely more correct.
    Update: Added -rubygems option to ruby command. If you'd prefer to not use this option, check the comments below for ways to use RubyGems in a Ruby script.

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on November 25th, 2008 by Ben in Hacking, Tools.

  • Displaying code on your blog

    A few weeks ago, I wrote about my desire for an awesome embeddable code widget.The most common solution that people suggested in the comments (and on the thread on Stack Overflow) was SyntaxHighlighter. I had seen the SyntaxHighlighter (SH) widget on a few blogs and was impressed, so I decided to install the WordPress plugin. The installation was easy enough, but unfortunately the plugin comes with a slightly old version of SH. Luckily, it was really easy to download the newest version from the SH site and drop it into the plugin.

    Now we can just wrap code in <pre name='code' class='ruby'>...some code...</pre> and it will look like this:

    class Foo
       def bar
         puts "Hello, world!"
       end
    end

    Pretty sweet! In fact, we ended up converting all of the code snippets on our blog to use SH.

    Although SH is really, really cool, it does suffer from inherent drawbacks: it has to be installed and it has to be periodically updated. What I initially described in my previous post was something simpler - a web app where you could easily post code and then embed it in your blog. In other words, Pastie with a YouTube-like embed feature.

    Dirceu Jr. pointed out Gist from GitHub, which is exactly what I was looking for. Even without signing up, you can post code (like so) and then embed it in your blog.

    Dirceu Jr. even wrote a WordPress plugin if you really want to install something! The only weird thing is that while the embedded code is nicely syntax-highlighted, the original gist is not for some reason. Update: Yoan pointed out that you can get syntax-coloring by naming your gist properly (I renamed my gist foo.rb and it worked). It's still not clear to me why it doesn't work if I manually select 'Ruby' as the language for an unnamed gist, however.


    Finally, while SyntaxHighlighter supports the most popular languages (and therefore is likely to be fine for most programming blogs), Gist supports a truly insane number of languages, making it a better choice if you want to post code snippets of say, Lua, Erlang, or Haskell.

    Language SyntaxHighlighter Gist
    Popular languages
    ActionScript X
    Bash X
    C X
    C# X X
    C++ X X
    CSS X X
    Delphi X X
    Diff X
    Erlang X
    HTML X X
    Haskell X
    Io X
    Java X X
    JavaScript X X
    Lua X
    OCaml X
    Objective-C X
    PHP X X
    Perl X
    Plain Text X
    Python X X
    RHTML X
    Ruby X X
    SQL X X
    Scheme X
    Smalltalk X
    Smarty X
    VB or VB.net X X
    XML X X
    Other crazy stuff
    Batchfile X
    Befunge X
    Boo X
    Brainfuck X
    Common Lisp X
    D X
    Darcs Patch X
    Dylan X
    Fortran X
    GAS X
    Genshi X
    Gettext Catalog X
    Groff X
    HTML+PHP X
    INI X
    IRC logs X
    Java Server Page X
    LLVM X
    Literate Haskell X
    Logtalk X
    MOOCode X
    Makefile X
    Mako X
    Matlab X
    MiniD X
    MuPAD X
    Myghty X
    NumPy X
    Python Traceback X
    Raw token data X
    Redcode X
    S X
    Tcl X
    Tcsh X
    TeX X
    Text only X
    VimL X
    XSLT X
    c-objdump X
    cpp-objdump X
    d-objdump X
    objdump X
    reStructuredText X

    Both of these projects provide great-looking ways to display code on your blog. If you know of other projects that you like, let me know in the comments.

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on November 13th, 2008 by Ben in Tools.