Esc2

Confessions of the Unix-Deficient

Okay, fine, I'll admit it... When it comes to shell scripting, I don't know my Bash from my Tsch. My command line abilities reached an all time high when I figured out how to pipe lines into 'grep'. I still hold my breath any time I use 'cat' and I say a quick prayer before firing up 'vim'. I must have suffered some head trauma because I can't remember a thing I learned from my 'Unix for Macs' book.

Despite these deficiencies, however, I've still wanted to get into shell scripting for one reason - automation. Rails and Textmate have helped to DRY up my day significantly, but I still waste time and, more importantly, attention on simple, routine tasks. I knew that I wanted my first task to be automating the process of opening up all the programs and windows I need for a project. I wanted to be able to simply type 'fire_up my_project' into iTerm and have it open a tab for the server, a tab for the console and a tab for the project directory. I wanted it to then open the project in TextMate (without the pesky directories like /doc and /log) and then open the site in Firefox.

I knew this was all possible, but how much Unix wizardry was I going to have to learn?

Ruby to the Rescue

Thankfully, it didn't take me long to realize that shell scripts don't have to be written in Bash, they can also be written in Ruby! All it took was a little setup and I was ready to automate.

First, I needed a place to put my new commands. I decided to create a /bin directory in my home directory (ie ~/bin). I then needed to add this to my $PATH by inserting the following at the bottom of my bash_profile (to access this file, use mate ~/.bash_profile in the console).

export PATH="~/bin:$PATH"

Now any file in this directory can be accessed as a command from the command line. I created a file in /bin called 'fire_up' (no file type suffix) and set its permissions to be executable by typing this in the command line:

chmod 755 ~/bin/fire_up

In order to be able to use Ruby in this script, the Ruby shebang needs to be the first line in the script:

#!/usr/bin/env ruby

Once that's in there you can use all the Ruby you want. Arguments passed into the script from the command line are stored in the ARGV array.

Bringing iTerm to Life

Small Print: I should mention that the following solution is only going to work for the iTerm console (pick it up at http://iterm.sourceforge.net/index.shtml), it will not work with Apple's Terminal program.

Though I now had the flexibility and power of Ruby at my disposal, I still wasn't sure how I could use it to control iTerm. After a little poking around, I found that iTerm supports Applescript. Using Applescript I would be able to fully control iTerm's windows, tabs, colors, the works. After a bit of work, I was able to wrap these Applescript commands into an easy to use, fully Ruby library I call ItermWindow. The class is used like this:

# EXAMPLE - Use the current iTerm window, cd to a project 
# and open in TextMate, launch the server and the console 
# and title them

  ItermWindow.current do |window|
    window.open_tab :project_dir do |tab|
      tab.write "cd ~/projects/my_project/trunk"
      tab.write "mate ./"
      tab.title = "MyProject Dir"
    end
    window.open_tab :server do |tab|
      tab.write "cd ~/projects/my_project/trunk"
      tab.write "script/server -p 3005"
      tab.title = "MyProject Server"
    end
    window.open_tab :console do |tab|
      tab.write "cd ~/projects/my_project/trunk"
      tab.write "script/console"
      tab.title = "MyProject Console"
    end
  end

Full documentation on the rest of the ItermWindow functionality is located within the class file.

So feel free to make your own implementations with the ItermWindow library, hopefully it will be a valuable tool in removing the routine tasks from your day.

Download or fork ItermWindow on GitHub now!



Partials_article_image

A Problem with Partials

Partials are incredibly powerful and flexible tools for a Rails developer; they help to DRY up view code, contextualize distinct presentational ideas and modularize markup for use in HTML or Javascript. It's been my experience, however, that each developer seems to use partials in a different way and, while I appreciate the value of personal coding style, these variations can cause confusion between developers.

The following techniques have proven to be 'best partial practices' for my fellow developers and myself. Adhering to these ideas helps us to keep our code consistent, legible and portable.

Keeping Organized

Organization and naming conventions are two initial hurdles in developing effective partials. It is an easy mistake to start arbitrarily organizing and naming partial files without thinking through their roles within the application.

I think that one pitfall is using (or at least over-using) a /views/shared directory for storing partials that will be used by many controllers. I used to use the /shared folder after seeing it used in the prominent Rails books and tutorials, and initially the logic of such a directory makes sense (especially before REST became the norm). That logic breaks down, however, when virtually ALL of your partials exist in that folder! If partials are meant to be reusable and flexible, shouldn't they all be in the shared folder? This is what would happen to me, and suddenly my file names lost a lot of meaning. What does the partial shared/thumbnail show? What about shared/favorite?

Certainly you can simply use more concise naming (user_thumbnail, favorite_video) but I have found that it's best to place these partials in the view folder of the related resource. There's nothing magical about the /shared directory, it's just as easy to use :partial => 'users/thumbnail' as it is to use :partial => 'shared/user_thumbnail'. I find storing the partial in /views/users, /views/videos, etc. helps to clarify the partial's function and keeps my files in order.

Another good practice is utilizing singular and plural naming conventions. In a recent project I was using two partials with poor names: shared/user_block and shared/user_thumb. The user_block partial accepted an array of Users as the :object and passed it on as :collection to the user_thumb partial, placing it all in a wrapper. I found that a name like user_block doesn't help me remember what the partial does - does it display a block of users, or one user in a block? By renaming my partials as users/thumbs and user/thumb, respectively, I was able to clarify their purposes and make it obvious which would display a single thumb versus a collection of them.

One other pitfall is mixing up where wrapper HTML is stored. A sidebar, for example, may have a series of modules that all use a common wrapper and header markup. Some of these modules are stored in their own partials, so should the wrapper markup go inside the partial? Or should that markup stay in the view file and wrap the render method call? Either might be appropriate given any set of circumstances, but the most important thing to remember is to keep it consistent! Placing the wrapper in one partial but leaving it out of another can only lead to confusion down the road.

No Partial is an Island... or is it?

In software development modular design is king. The ability to create portable, flexible and self-sufficient chunks of code significantly helps speed up development and code reuse. So why not apply the same principles to partials? Partials, like any other code, can become much more robust and useful when given good defaults, error handling and documentation.

If a partial were a method then :object, :collection and :locals would be the arguments. Unlike arguments, however, there is no built-in way to ensure that these passed variables are valid or even present. It is simple, however, to mimic this functionality within the RHTML template. For example, the following partial displays a series of thumbnails for recently added videos (the partial name is videos/recent_thumbs):

  <% limit ||= 10 %>
  <% videos = recent_thumbs || Video.find_recent_videos(limit) %>
  <div id="recent_video_thumbs">
    <%= render :partial => 'videos/thumb', :collection => videos %>
  </div>

Default values are supplied for each variable that can be passed in to the render method. The number of videos displayed (limit) can be passed in through the :locals hash, otherwise it defaults to 10. The :object parameter, which reads as recent_thumbs within the partial, will be used if given; otherwise, the partial uses the Video class to find the most recent videos. This partial can be passed some, all or none of those parameters and will still work correctly.

But wait! Isn't this placing application logic in the view?! Isn't this strictly taboo?! Though it may approach that line, I believe this is still clean code. The actual logic is still stored within the Video#find_recent_videos method and this behavior is only the fallback behavior, not the primary functionality. In this situation it works, but that may not always be the case. If a fallback collection would not be available, proper error handling should be used instead:

<% raise ArgumentError, "The videos/recent_thumbs partial requires an array
of Video objects passed as :object." unless recent_thumbs %>

Using these techniques achieves two goals. First, the developers are given more flexibility and less trouble with partials that can 'take care of themselves.' These partials can be easily dropped into a view and rely on defaults that can later be easily overridden. The developers are also given some 'documentation' about how the partial works. It may not be rDoc, but these variable 'declarations' at the top of a partial make it very clear what :locals it takes and whether it takes an :object and/or a :collection.

With a Little Help From My Friends

When passing a collection to a partial, I have often found the "collection_name_counter" variable to be very helpful (ie the thumb_counter in :partial => 'thumb'). This dynamic variable, built-in by Rails, gives the current index within the passed collection. As helpful as that can be, I usually find it to be incomplete without having access to the collection itself. Without the collection array I have no idea if the current index is the last item, the first item or any in between!

For a while I simply passed in the collection both as :collection as well as :locals => {:collection => @collection}. It worked, but it wasn't very DRY. To fix this I created a simple monkey patch module called PartialEnhancer. This hacks the partial code so that you have access to two more dynamic variables. If the partial were named "thumb" the variables would be thumbs and thumbs_count. The thumb_count variable simply stores the length of the collection for comparison with thumb_counter while the thumbs plural variable accesses the collection array directly. It's now very simple to find where a given object is within the overall collection within a partial.

Another partial-related problem struck me when I began working on a project that used a great number of nested partials within nested layouts. Whenever I had to change some view markup it was often very difficult to figure out where that markup was! Which stacked partial, layout or view did it belong to? To help me find my way I created another monkey patch module called PartialExposure. This module hacks the render method so that every layout and partial is wrapped in an HTML comment. Each comment displays the filename and path of each partial file and reveals exactly where it starts and stops. Thanks to that module I can now instantly figure out where display code exists, even on projects that I am not familiar with. Just make sure you only use it in Development!

Download the PartialEnhancer and PartialExposure files.




RSS Feed


CATEGORIES


ARCHIVES


BOOKMARKED


Add to Technorati Favorites