Not only must the spice flow... but the flow must also spice!

September 28, 2009

Announcing the update_attribute gem on github!

This is just an announcement of my new (and first ever) plugin/gem! It's a humble little gem (of a gem) called update_attribute and here is its description:

Rails gem for simplifying calls to update_attribute on Active Record objects by allowing you to replace "attribute" (in update_attribute) with the actual name of the attribute to be updated and then just pass in the value to update that attribute to. The passed in value may be a string or a symbol (symbols will be converted to a string for you).


Usage and Examples:

Wihtout update_attribute:

    <active_record_object>.update_attribute(<attribute>, <value>)

With update_attribute:

    <active_record_object>.update_<attribute>(<value>)

Examples:

  user = User.find_by_username("Paul")
    # => #<User id: 1, username: "Paul", email: "atreides@muaddib.com", ...>
  user.update_username "Muad'Dib" # => true
  user.reload.username # => "Muad'Dib"

  user.update_username :Atreides # => true
  user.reload.username # => "Atreides"

  user.email # => "atreides@muaddib.com"
  user.update_email "paul@atreides.com" # => true
  user.reload.email # => "paul@atreides.com"

I plan to use this as a simple development environment booster as it's mainly just a keystroke saver. By development environment booster I just mean that it will be required (included) by my personal (non source-controlled) config/environments/development.rb file and will just be there to boost my productivity a bit when debugging with ruby-debug or when working in the Rails console (where I use shorthand for everything I can!).

For the curious, making this gem was above all fun! But it was also a little bit weird... (at first I started going down the path of using a generator to create a base for my new gem, but that ended up being too clunky for me!) After all, I think github has done a pretty good job of making gem builds simple as basically all you've got to do is figure out how to add a <project_name>.gemspec file to your repo (as well as a Manifest and a CHANGELOG I found out). The best resource on that process that I found (better than the generators I tried) was, as usual, the one proposed by Ryan Bates in his Making a Gem railscast. And then of course the GitHub RubyGems guide was also very concise and helpful when things weren't quite working properly. Also, one thing that neither of these resources ever mentioned is that github even sends you a status email indicating whether or not the build on your gem passed or failed and why. Pretty cool!

September 26, 2009

Viewing source for local gems in Windows

As a Rails programmer, every once and a while I want to look at the source files for Ruby gems installed on my system. The way I have done this in the past was to go to github and search for the gem, and then navigate through the source tree 1 click at a time. But this is slow and handicaps you from the supreme navigational powers and otherwise aesthetic delights of your favorite text editor! And while I always sort of knew that all the gem sources were sitting around on my file system somewhere I just hadn't put in any thought to quickly and easily accessing them. So today I decided that this had to change!

In my post about setting up your Rails server and console with Console2 in Windows I also described how to set up a macros file which could be loaded in to the command prompt when Console2 starts up with this command line argument: -r "/k doskey /macrofile=C:\macros". Today I'm going to extend the utility of the macros file a bit and leverage E Text Editor's command line tool for opening the source directory for locally installed gems in Windows - as a project! If you're not using E then I'm sure your editor, whatever it may be, can do something like this too, though, so follow along.

To get started, open up your macros file (for me this is located at C:\macros) and add the following three lines:
gls=dir/w %GEMS%\$*
gll=dir %GEMS%\$*
ge=e %GEMS%\$1

This defines 3 new (though somewhat familiar) aliases, all of which I have namespaced with a "g" for gem - but you can name these anything you want, of course.

gls = horizontal listing of all the gems in your local gems folder.
gll = vertical listing of all the gems in your local gems folder.
ge = open the passed in folder (i.e. gem name and version number) as a project in E Text Editor

Why not just use gem list, you ask? Well, using the gls and gll aliases is helpful because all gems live in a folder designated by both their name and version number - which is how rubygems keeps multiple gem versions separate. And since copy + paste is faster than typing this stuff out getting the actual directory listing through gls or gll is of great convenience. You'll see exactly what I'm referring to in a minute, but first let's finish the macros setup...

Ok, so the only thing we really need to do now is create that %GEMS% environment variable (or alternatively, just use the full path to your Ruby gems in your macros file instead, but this is easy enough and adds some flexibility). Again, refer to this article if you're not sure how to add an environment variable in your version of Windows.



Note: The path to your Ruby gems folder is relative to where you installed Ruby at, so make sure that the path shown in the above image is correct for your system before entering it in. But for me it was C:\Ruby\lib\ruby\gems\1.8\gems.

Great, now let's try out our new aliases! Again, if you already followed along with my post about Console2 then you should be able to just fire up Console for your project and go (but make sure to close and reopen Console if it was already open during the previous steps - to reload the environment). Otherwise, if you're using the vanilla Windows command prompt you're going to need to 1) create and 2) load in your macros file to your current session with doskey /macrofile=C:\macros (assuming C:\macros is the path to your macros file).

Anyway, first enter gls to get the gems directory listing:



And then all you've got to do to view source on one of the listed gems is type ge <gem_directory_name> - which I propose that you fill in the <gem_directory_name> by copying and pasting it out of the directory listing. For example, to view source on the map_by_method gem, the full command would be ge map_by_method-0.8.3.

Remember: in Console2 the default for copying and pasting is to hold down Shift and drag the mouse (copy) and then middle mouse button click (paste).





Too easy! And by the way, if you want to get E to go back to your rails project folder, I find that the quickest way to do this is to go back to your command prompt and enter e . which opens e to the current path/folder. Or you can pass any file or folder path to the e command line tool to open it in E (much like the mate command for TextMate on the Mac).

So that's it! Easiest way I have found to do this in Windows yet (but please let me know if there's a better alternative!). Thanks again Console2 and E!

September 13, 2009

Creating irb and ruby-debug initializer files (.irbrc and .rdebugrc) in Windows

This isn't exactly a new topic, but I wanted to document how to setup both .irbrc and .rdebugrc at the same time. Basically these files are simple initialization scripts for irb (and thus the Rails console) and ruby-debug (the de facto debugging tool for Rails). The challenge here is that neither the irb nor the ruby-debug windows bindings specify where these files should be located. But they will reference the environment variables IRBRC and RDEBUGRC respectively, which can specify a file location!



First, so that we're on the same page, make sure that your version of Windows properly uses the %HOMEPATH% environment variable. The rest of this article is dependent upon it. Windows Vista uses this environment variable by default to point to \Users\<Username>\. To check, open up a command prompt and enter: echo %HOMEPATH% and you should get back your home path.


If instead you see just the string %HOMEPATH% echoed back to you then you'll need to set up an environment variable with this name that points to your home path. Or you can just use the full path anywhere I mention %HOMEPATH% below. In Vista the full path is C:\Users\<Username>\ or in XP it is C:\Documents and Settings\<Username>\.

If you're not sure how to add environment variables refer to this article.

Now that that's cleared up, let's get started.

1) Create the IRBRC and RDEBUGRC environment variables as in:


2) Create the files themselves in your %HOMEPATH% directory.

2a) In order to create the .irbrc file you will need to use your favorite text editor's Save As... function since Windows Explorer will not let you create a file that is all extension and no name (it sees ".irbrc" as being a no-name file with an extension of "irbrc"). So just open up E Text Editor or Notepad or your favorite text editor and save a new document as .irbrc within your %HOMEPATH% directory.


2b) Use the same process to create the rdebug.ini file. What's that? Yes I do mean rdebug.ini. Even though our RDEBUGRC environment variable points to a file called _rdebugrc the actual file should be called rdebug.ini! Otherwise, the file is not found and therefore not loaded up when the ruby-debug debugger starts. And honestly, I don't know why... but this setup is just what worked for me. Go figure!

OK. Now, as for what goes into these init files... well that's up to you! But the following is what I have.

Note: some of the requires in the below example .irbrc file will require corresponding gem installations.
  1. require 'map_by_method' => Install this gem with gem install map_by_method. Here's an article on map_by_method (also by Dr Nik).
  2. require 'what_methods' => Install this gem with gem install what_methods. There's not really a definitive source on what_methods that I can see, but basically what_methods is a way to see which methods, when performed on an object, return a particular value. For example:



Inside of .irbrc: (based on this article by Dr Nik)

require 'rubygems'
require 'irb/completion'
require 'map_by_method'
require 'what_methods'
require 'pp'

IRB.conf[:AUTO_INDENT] = true


####################################################################
# From http://blog.nicksieger.com/articles/2006/04/23/tweaking-irb
####################################################################
ARGV.concat [ "--readline", "--prompt-mode", "simple" ]

module Readline
  module History
    LOG = "#{ENV['HOMEPATH']}/.irb-history"

    def self.write_log(line)
      File.open(LOG, 'ab') {|f| f << "#{line}\n"}
    end

    def self.start_session_log
      write_log("\n# session start: #{Time.now}\n\n")
      at_exit { write_log("\n# session stop: #{Time.now}\n") }
    end
  end

  alias :old_readline :readline
  def readline(*args)
    ln = old_readline(*args)
    begin
      History.write_log(ln)
    rescue
    end
    ln
  end
end
Readline::History.start_session_log

# Remember irb command history across sessions
require 'irb/ext/save-history'
IRB.conf[:SAVE_HISTORY] = 100
IRB.conf[:HISTORY_FILE] = "#{ENV['HOMEPATH']}/.irb-save-history"
####################################################################

# Clear screen
def cls
  system('cls')
end

# Return a list of methods defined locally for a particular object.  Useful
# for seeing what it does whilst losing all the guff that's implemented by its parents (eg Object).
class Object
  def local_methods(obj = self)
    (obj.methods - obj.class.superclass.instance_methods).sort
  end
end

# Call this method if you'd like to display all of ActiveRecord's generated
# SQL statements inside of your Console or ruby-debug session
def active_record_logging(stream = $stdout)
  ActiveRecord::Base.logger = Logger.new(stream)
  ActiveRecord::Base.connection_pool.clear_reloadable_connections!
end
####################################################################
# Hirb
####################################################################
# http://tagaholic.me/2009/03/13/hirb-irb-on-the-good-stuff.html
# http://tagaholic.me/hirb/doc/classes/Hirb.html
require 'hirb'
require 'yaml'
class Hirb::Helpers::Yaml
  def self.render(output, options={})
    output.to_yaml
  end
end
Hirb.enable({:width => 204, :height => 32}) # Specifies my console size
puts ".irbrc successfully loaded"


If your .irbrc file loads successfully you'll see the line ".irbrc successfully loaded" in your Rails console. If not then something isn't right! .irbrc failures will fail silently so try adding a puts statement higher up in the file to debug any problems. And again, make sure your HOMEPATH environment variable is working as the above script depends on it.

Want more? Check out this article for some pretty advanced initialization scripts.


Inside of rdebug.ini:

set autolist
set autoeval
set autoreload

If your rdebug.ini file loads successfully then you will automatically get a code listing in your Rails server console when breaking at a debugger point. As a ruby-debug quirk, I have found that autoreload doesn't always reload files automatically. So if your source code in the Rails server console ever looks out of date type in set autoreload again, at the debugger prompt. Just typing autoreload (without prepending "set") used to be enough, but as of ruby-debug v0.10.x will yield an error trace (I think this is probably a Windows binding artifact). But in any case, retyping the full set autoreload will do the trick when needed.

For instruction on using ruby-debug, check out this very thorough article, watch the railscasts screencast on ruby-debug, or just enter the help command at the prompt while debugging and play around. Or here's a quick reference that will get you most of the way:

l   => (short for "list") list the next frame of code
l=  => (short for "list" with "=" meaning current frame) list the current frame of code (this is the one I always use.)
n   => (short for "next") skip to next line
s   => (short for "step") step into next line
c   => (short for "continue") continue code execution normally. Future "debugger" statements will re-execute the debugger as normal.

Well that's it for now. Happy coding!

September 9, 2009

Windows, Rails and Console2 in it together... how?

I have always believed that when using computers, one must constantly be looking for ways to let the computer do the repetitive work - this is after all what computers are best at! It is easy to lose sight of this, however, and hack away at the same old commands day in and day out. Well, I say enough!

The problem: Starting up a Rails server, console, and dedicated command prompt multiple times a day, and dedicating valuable screen and taskbar space to multiple command prompt windows just isn't good enough! (This is especially true when working on multiple projects.)

The solution: Console2 and a shortcut file (or one shortcut file per project). I assume here that you may be new to Console2 or have limited experience with it, so don't be afraid. Charge ahead.

First, download and install Console2 beta: http://sourceforge.net/projects/console/. I installed mine at C:\Console2.
Console is a Windows console window enhancement. Console features include: multiple tabs, text editor-like text selection, different background types, ... [etc.]
It is important to keep in mind that Console is not a Windows shell (command prompt) replacement like Windows Power Shell or Cygwin. Instead, it is basically just a fancy wrapper around the Windows shell. And after playing with Windows Power Shell I have determined that I have no immediate need to use it... but you might. And if you do then that's just fine because you can pull up Windows Power Shell in a tab inside of Console just as easily as you can pull up the Windows command shell. You'll see how to later.

Let's jump right into the Console2 configuration options. The following are my settings. (At least the juicy ones.)



One thing in this screen that I was disappointed to learn was that it is not possible to set the foreground text color for each tab individually. There is only one global text color setting for all tabs and it is right here (above) on the Appearance tab. So I chose to use white as mine. Fortunately it is possible to customize the background color for each tab, though, as we'll see in a minute.


I like to trim up my console a bit, removing the excess menu and toolbars, etc. One can always access these by right-clicking anywhere on the console window later.


The "Tabs" tab is where the magic starts happening. In here you can add predefined tab names which we'll be referring to (by name) later on. For the rails environment, then, we will want to create 3 tabs. 1) cmd, 2) Server, and 3) Console. Above I have pictured my Server tab. Notice the shell being used is "cmd.exe" - the standard Windows shell. The "Startup dir" setting will override the default startup directory set either back in the first page of settings or in a Windows shortcut. I set mine to my root projects folder, C:\code. This is just because I didn't want to limit myself to any one project yet. Besides we'll be overriding this yet again in a bit.


In the Background tab, you can set the background color for, in this case, your Server window. As you can see my Server background is green. I have my Console background set to red, and normal command prompt is set to black. Easy enough!

Ok now that Console is set up, let's get into the meat and potatoes of this post. Create a shortcut to Console.exe and place it on your desktop for now. Then right-click on the shortcut and choose properties. Now, enter the following crazy long command into the Target field (in the Shortcut tab):
C:\Console2\Console.exe -t Server -d APP_NAME -r "/k doskey /macrofile=C:\macros && ruby script/server -b 127.0.0.1 -p 80 --debugger" -t Console -d APP_NAME -r "/k doskey /macrofile=C:\macros" -t cmd -d APP_NAME -r "/k doskey /macrofile=C:\macros"
Note: The Target field in a windows shortcut can only hold up to 260 characters. The above is cutting it close to that threshold. Also, remember to replace all 3 instances of the token "APP_NAME" with the name of your rails app. Since we set the startup folder for your Server, Console and cmd tabs to your rails project root (in the Console 2 Tabs settings above) this is a valid path to your rails app.

What is this crazy long command doing? Let's break it down...

  • C:\Console2\Console.exe = the Console2 program executable
  • -t Server = use the Console2 tab named "Server" that we defined earlier.
  • -d APP_NAME = startup directory for your Rails app. This way the shell will start up in the Rails app directory specific to this shortcut.
Now for the -r "/k doskey /macrofile=C:\macros && ruby script/server -b 127.0.0.1 -p 80 --debugger"... This is a bit of a special case (and also completely optional)... We could have just used -r "/k doskey /macrofile=C:\macros" here, but I wanted to perform 2 commands for this tab after Console2 starts (the -r flag means "run the following command when Console2 starts"). Here's the breakdown of the full command:
  • /k is just a necessity for the windows cmd.exe shell.
  • doskey /macrofile=C:\macros means run the doskey command, passing it the macrofile switch with a value of "C:\macros". This is an important file that we have not set up yet but will in a minute.
  •  && ruby script/server -b 127.0.0.1 -p 80 --debugger = after initializing the macros file, startup my Rails server. You may want to customize your rails server startup script here though, perhaps to use a different port.
From there, the rest of the text in the Target field is just repeating itself to set up the 3 different tabs, all defined similar to the above break down. Remember we're trying to save screen real-estate so we're starting up a Server tab, a Console tab and a cmd tab all in one Console2 window from just one shortcut file. Makes sense? I found the above Console command line switches in the help file, by the way, which is located at C:\Console\console.chm if you installed Console2 to C:\Console. Now on to the C:\macros file.

Note that I called this file "C:\macros" to save on space from e.g. "C:\macros.txt", but this is just a text file. I saved 12 characters on listing this file 3 times in the Target field above, and I needed to save that space to fit within the 260 character limit of the Target field in windows shortcuts!

Inside of C:\macros I have the following:
ls=dir/w $*
ll=dir $*
cat=type $*
..=cd..
grep=find "$1" $2 
mv=ren $*
rm=del $*

m=type C:\macros
me=notepad C:\macros
mr=doskey /macrofile=C:\macros

gls=dir/w %GEMS%\$*
gll=dir %GEMS%\$*
gcd=cd %GEMS%\$*
ge=e %GEMS%\$1

s=ruby script/server -p 80 --debugger
s80=ruby script/server -p 80 --debugger
s3000=ruby script/server -p 3000 --debugger
s3001=ruby script/server -p 3001 --debugger
p=mongrel_rails start -e production -p 80
p3000=mongrel_rails start -e production -p 3000
c=ruby script/console

rr=rake routes
rre=rake routes | e
rrc=cls && rake routes
rdm=rake db:migrate $*
rdmr=rake db:migrate:redo $*
rlc=rake log:clear

UPDATE: I've added the contents of my C:\macros file as of 11/1/2009. I've added a section for viewing, editing and reloading the macros file (m, me, mr - repsectively) and a few other goodies. For more on what's going on with the g* macros, check out my post on Viewing source for local gems in Windows.

You'll probably recognize what's going on here. I'm setting up basically the equivalent of aliases - a real repetitive task saver! Feel free to add any aliases that you'd like, of course! Take note of my two favorite ones: s=ruby script/server -p 80 --debugger and c=ruby script/console. With these I can start my Rails server simply by typing s and hitting enter. Or I can start up my Rails console by typing c and hitting enter.



Ok now we're all set. You should be able to just double click the shortcut you made on your desktop and you'll see your Server pop up and immediately start running, your Console ready and waiting in the 2nd tab, and a standard command prompt in the 3rd tab, also ready and waiting - for you to issue rake commands (like rake routes)! Now that's about as warm a welcome as coming home to your dog after work! Oh and I don't like to start my Rails console automatically along with the server because sometimes it can interfere with the Server output buffer for some reason, so I just manually start it with my c alias when I'm ready to.

One last suggestion: Add a shortcut key combo to your windows shortcut file on your desktop! I typically use Ctrl + Shift + FIRST_LETTER_OF_RAILS_APP_NAME. This way you can start your Server, Console, and cmd prompt up almost as fast as you can think about it.

A newbie hint: When working with Console, if you'd like to copy some text, the default behavior has you hold down Shift while dragging the mouse. At first I thought this was weird, but now I find it a welcome alternative to the Windows command prompt options... (either finding "Mark" in the Edit menu, or enabling the "Quick Edit" option). Quick edit made it too easy to get in trouble with the Rails server by accidentally single-clicking in the server window to give it focus. This, of course, would put a selection box on the server and thus would freeze the process until you escaped out of the selection (during which time your browser can't reach the server for no obviously apparent reason)! With Shift + Mouse Drag this complication is much less likely. But of course, if you'd like to change this behavior you can - in the Console2 Settings dialog.

Cheers!