James Crisp

Software dev, tech, mind hacks and the occasional personal bit

Category: Ruby / Rails Page 3 of 6

“Ruby for Rails” by David Black

Ruby For RailsRuby for Rails by David Black is a fun read that takes concentration but repays it with little epiphanies that explain syntax and language features that you had previously taken for granted.

The book aims to “help Rails developers achieve Ruby mastery”. The coverage of Ruby features is not complete and there are some concepts missed that I would have liked to have read more about (eg, how do instance variables work under the hood?). There are also a number of introductory chapters on Ruby and Rails and some chapters devoted to a sample Rails project (R4RMusic) which I flicked through but didn’t add much value for me (they are also a little dated). By far, the most interesting parts of the book for me were on the Ruby type system, ‘self’ in various situations and how method look up works with modules and inheritance.

An area of Ruby that I had not previously explored was adding singleton methods to instances (like what you can do in Javascript). Eg,

o = Object.new
def o.say_hi
  p "hi"
end

>> o.say_hi
"hi"

or alternatively

o = Object.new
class << o
  def say_hi
    p "hi"
  end
end

Now, the interesting thing is that this is the basis for the whole class system in Ruby!

Classes are just a special type of object, and when you add class methods, you are really adding singleton instance methods to the class object for the type.

Ie, when you do something like:

class Cars
  def self.find_all
    ...
  end

You are actually creating a new object, of type Class which has a singleton method called 'find_all'. 'self' in the code above is the Class object, so def self.xxx is adding a singleton method to it.

This also explains the alternative syntax for adding class methods:

class Cars
  class << self
    def find_all 
      ... 
    end
  end

The same thing could be done by saying:

Cars = Class.new
Cars.instance_eval { def find_all; ... end; }

In Ruby, the type and class system is not very different from the normal objects you work with every day. I find this really quite cute and internally consistent.

The way the method search path works in ruby was also nicely explained in the book. Basically, finding a method starts at the top of the list below and stops as soon as a method with a matching name is found (ie, that responds to the message sent to the object):

  • Singleton methods on the object
  • Methods defined by the object's class
  • Methods defined by modules mixed in to the class
  • Methods defined by parent class
  • Methods defined by modules mixed into parent class
  • Repeat checking parents until get to Object
  • Methods defined on Object
  • Methods defined on Kernel (module mixed into Object)

This also explains why you can always call methods like 'p' from anywhere. They are coming from Kernel which is mixed in at the top of the inheritance tree for your object. Another case of internal consistency - there's no 'special' mechanism for these seeming globals.

Overall, I enjoyed the book and would recommend anyone having a read who has worked with Ruby and Rails but would like to dig a bit deeper.

Mephisto Contact Form Plugin Moved to GitHub

Sorry the the confusion, anyone who has been checking out the the Mephisto Contact Form Plugin from the old SVN repository. The latest version with an update for Rails 2.3 is at:

http://github.com/jcrisp/mephisto_contact_form/tree/master

Spying on Instance Variables in Ruby

A little while back, a few colleagues and I were spiking a proxy concept based on extending an existing web server. We wanted to check out an instance variable (eg, @very_secret) in a framework object which did not have an accessor. In the past, we’d used send (eg, secretive_object.send :hello_private) to get at privates, but send is only for methods. We were just digging around doing some debugging, so we opened the relevant class and added a public accessor for the instance variable to see what was happening. However, we thought there must be a more elegant way to do access instance variables outside the class, and one has just come to mind (at last!):

secretive_object.instance_eval { @very_secret }

instance_eval lets us run the code block in the context of secretive_object. Ie, self == secretive_object, so we can get at all the hidden stuff.

It’s a rather different approach to other languages like C# and Java where accessing private variables and private methods are part of a reflection/introspection API.

Review: “Deploying Rails Applications” by Ezra Zygmuntowicz et al.

Deploying Rails Applications: A Step-by-Step Guide by Ezra Zygmuntowicz, Bruce Tate and Clinton Begin is a good read, if a little dated. It was published in May 2008, and you can see that things have moved on a little in the Rails world since then. None the less, quite a lot of the information is still relevant and useful.

The book covers some basic Rails and version control concerns at the start, then rapidly launches into chapters devoted to Rails hosting options available from shared hosts to virtual and dedicated servers. The advice given is good and is in line with my experiences. Unix configuration is given in depth which would be very handy if you had not set up a server before. Next is a good discussion of Capistrano and automating deployments. The examples all use subversion. However, these days I expect the majority of Rails source code is pulled with Git. There is also a chapter on managing mongrels and setting up monitoring solutions. This is still relevant if you want to use mongrels, however these days Passenger is probably the best choice, and it does not have such complex management and configuration requirements. The scaling out chapter is useful and pulls together handy information including details on MySql replication/clustering. There’s a chapter on deploying on Windows and also some suggestions around performance and profiling.

I haven’t come across another book that brings together a structured collection of useful information to help you move from running rails locally to having a cluster of scalable production servers and the automated deployment process required to support it. Despite being too old to cover Git and Passenger, I’d still recommend having a read of this book if you’re at the stage of planning to launch a Rails site or looking to scale your VPS up to a cluster.

Linux VirtualBox vs Windows for Rails Dev

So yes, everyone has heard that Mac OS X and TextMate is the epitome of Rails development, and that it is so awesome that it brings tears of joy to developers eyes, &c. However, for those of us who either don’t have a Mac, or get to work on client provided hardware (often running Windows), there are a few options available.

Developing on Windows XP, with InstantRails is workable. It is easy to get everything you need and have your apps up and running quickly. However, performance is, well, quite frankly, terrible for anything you do on the command line. Mainly, this bites when running tests, doing migrations, generating files etc. Performance running Mongrel is good enough for development.

What about Cygwin? Subjectively, I found it provided similar speed to Windows Ruby/Rails.

So this brings us to virtualisation. Recently, I’ve been testing out VirtualBox running Ubuntu on top of Windows XP. This has had surprisingly good results. On the same machine, the virtual Ubuntu running Rails tasks has about 4 times (!!!) faster performance, even though it has less memory and system resources!

Here are some stats to give you and idea of the advantage.

Machine is a 2.4ghz quad core, 4gig of memory running Windows XP. Using VirtualBox 2.1.4 for virtualized Ubuntu Intrepid 64 bit, with 1.5gig of memory allocated. Figures are in seconds and approximate (taken with a wrist watch).

  generate scaffold db:migrate with no changes run tests for medium sized rails app
Windows XP & Instant Rails 7 7 25
VirtualBox Ubuntu on same Windows XP 1.5 1.5 6

Some of these commands / tests rely on hitting a MySQL database. However, I’m interested in overall development speed for both platforms, not in Ruby speed in particular, so I think it is fair game to include these in the results.

So if you want to do Rails Dev on Windows, I highly recommend trying a virtual machine running Linux!

Vim with find file for Rails (like TextMate)

In a fit of TextMate jealousy, several months ago, I scoured the web for a way to get find-file functionality info my favourite Ruby/Rails editor, vim. I was very happy to find that Jamis Buck had developed an aweseome plugin do to this. It is a little fiddly to install, but worth the trouble. Here’s some simplified steps to get you going.

  • Install Jamis’s ruby gem
    sudo gem install jamis-fuzzy_file_finder --source=http://gems.github.com
  • Download this fuzzyfinder script and pop it in your ‘~/.vim/plugin’ directory. Note that the most recent versions of this script are incompatible with Jamis’s plugin.
  • Grab the latest version of ‘fuzzyfinder_textmate.vim’ from http://github.com/jamis/fuzzyfinder_textmate/tree/master and pop it in your ‘~/.vim/plugin’ directory

Then, if you want to have a similar sort of light-weight Rails ‘IDE’ I enjoy coding with, see my config files below:

.vimrc

source $VIMRUNTIME/vimrc_example.vim
behave xterm
set nu
set tabstop=2
set shiftwidth=2
set softtabstop=2
set ai
set expandtab
set smarttab
let g:rubycomplete_rails = 1

map f :FuzzyFinderTextMate<CR>
map n :tabnew<CR>
map c :tabclose<CR>
map m :tabnext<CR>

let g:fuzzy_ignore = "*.svn"
let g:fuzzy_ignore = "*.swp"
let g:fuzzy_ignore = "*.jpg"
let g:fuzzy_ignore = "*.gif"
let g:fuzzy_ignore = "*~"

set nobackup

.gvimrc

source ~/.vimrc
set selectmode=mouse
set columns=100
set lines=50

In this set up, there are no chords etc. Instead, when not in edit mode, ‘n’ will open a new tab. ‘f’ will let you find a new file to open in the current tab. ‘c’ will close the current tab and ‘m’ will move between tabs. So in a normal workflow, you might decide to swap the file in the current tab for a new one (simply press ‘f’), or if you need another file open, hit ‘n’ for new tab, and then ‘f’ to load the relevant file. My text description doesn’t do it justice, but I find this works very well to get you to the file you want quickly, and let you have the files you’re interested in open all at the same time.

One last note, remember to start vim/gVim in the root of your rails directory.

Happy Vimming 🙂

UPDATE
These files are now available from my github dotfiles repository, including the gem inside of the vim/gems_required directory.

Contact Form For Mephisto updated for Drax 0.8

Mephisto Drax (version 0.8) introduces breaking changes for plugins. I’ve just finished updating the contact / feedback form plugin. It’s now working fine and tests passing.

Installation instructions are the same as before except that the ‘contact_notifier’ has moved from the ‘lib’ directory to the ‘app’ directory. It still needs to be updated to include your destination email address for contact mails.

If you’re a Mephisto plug-in developer, you might be interested in checking out my post on migrating Mephisto plugins to Drax. It’s based on my experiences with the contact_form.

Migrating Mephisto Plugins to Drax 0.8

There have been some major changes to Mephisto in the latest release (0.8 Drax) that break existing plugins. If you’re interested in migrating your existing plugin(s) over to Drax, read on.

Repository Move
First thing to note is that the Mephisto code base has moved from SVN to github.

Plugin Architecture Changes
There is no longer a base class for Mephisto plugins. Instead, you create Mephisto plugins using Rails Engines. If you’re migrating a pre-Drax plugin to Drax and Rails engines, you’ll most likely need to:

  • Remove your plugin file – there’s no base class for it any more so you’ll get errors like: ‘superclass must be a Class (Module given) (TypeError)’
  • Move your routes into a ‘routes.rb’ file in your plugin root directory.
  • In your plugin root directory, create an ‘app’ directory, with ‘views’, ‘models’ and ‘controllers’ sub-directories. Move your code files into the appropriate folders in the ‘app’ directory. These will be auto-loaded.
  • Remove various lines in your init.rb which manually add your plugin file directories to the load paths, if you have these.
  • If you inherit from the ApplicationController, add ‘unloadable‘ to your controller class. This will fix errors in development mode like ‘A copy of ApplicationController has been removed from the module tree but is still active!’
  • An example
    You can have a look at my contact_form plugin code. Revision 18 is before Drax and engines and uses the old approach. Revisions 19 and later are using Rails engines and will work with Drax.

    UPDATE: Latest code at GitHub
    http://github.com/jcrisp/mephisto_contact_form/tree/master

RiskAssess – Risk Assessments for Schools

I’ve been developing RiskAssess, an online risk assessment system for schools. RiskAssess helps teachers and lab assistants to quickly and easily produce risk assessments for laboratory experiments which meet Australian standards. RiskAssess should help decrease the number of accidents in school laboratories, and also help schools meet legal requirements.

I’m pleased to say that the site is now well and truly launched and we have schools doing risk assessments every day using RiskAssess. There’s still much to do and many new features to add, but so far we’ve had very positive feedback from the schools using the system.

On the technical side, RiskAssess is a Ruby on Rails site.

Loan Calulator: Monthly repayment and interest breakdown

Wondering if your loan repayment calculations have been performed correctly this month, taking into account interest rate rises and extra repayments? You might be interested in giving my monthly loan calculator a go.

As my home loan provider doesn’t show balances online, and only sends statements every 6 months, I like to ring up every month or two to make sure things are on track. I used to calculate interest, new balances etc in a spreadsheet / calculator but spent an afternoon writing a little Rails app to calculate it for me. Hopefully my little monthly loan calculator is of some use to you too.

Page 3 of 6

Powered by WordPress & Theme by Anders Norén