Digging deeper into Rails scopes

October 8th, 2015

Background

Recently I wrote a post about Rails scopes and lambdas in an attempt to clarify why it is so common to see the use of lambdas with Rails scopes. I now realise that I could have gone a bit further in my explanation.

A question that is sometimes asked is:

Why are lambdas used with Rails scopes? Why not procs or blocks?

To answer that question it is useful to first look at the implementation of the Rails scope method in ActiveRecord::Scoping::Named::ClassMethods.

Implementation Details

The implementation is as follows:

def scope(name, body, &block)
  unless body.respond_to?(:call)
    raise ArgumentError, 'The scope body needs to be callable.'
  end

  if dangerous_class_method?(name)
    raise ArgumentError, "You tried to define a scope named \"#{name}\" " \
      "on the model \"#{self.name}\", but Active Record already defined " \
      "a class method with the same name."
  end

  extension = Module.new(&block) if block

  singleton_class.send(:define_method, name) do |*args|
    scope = all.scoping { body.call(*args) }
    scope = scope.extending(extension) if extension

    scope || all
  end
end

Now let’s consider this implementation in conjunction with the following scope:

class Article < ActiveRecord::Base
  scope :created_before, ->(time) { where("created_at < ?", time) }
end

In this example, :created_before is interpreted as name and ->(time) { where("created_at < ?", time) } as body.

Block, Proc or Lambda?

Notice that body must be callable. So that rules out a block, which is simply a syntactic structure. However, it does still allow body to be a lambda or a proc.

Whilst it is technically possible for a proc to be used in conjunction with a Rails scope, a lambda is more useful because of the constraint that it must, unlike a proc, have a specific arity. For example, in the example above, Article.created_before must be called with one argument.

Summing up

Hopefully, that explains why lambdas are used with Rails scopes.

Of course, you’ll notice that the implementation of the scope method uses metaprogramming via :define_method to create a class method that could have been programmed directly.

Tags: rails ruby scopes lambdas | Comments (0)

Rails scopes and lambdas

October 6th, 2015

Recently I was asked a searching question that left me pondering. The questioner mentioned that he had been following The Rails Way and was puzzled by it’s emphasis on the use of lambdas in conjunction with Rails scopes.

At the time I could only offer a vague answer along the lines of it being a common idiom. I was not satisfied with my reply so committed to following up with a more definitive response.

Background

Ruby Lambdas

Firstly, let’s recap and clarify exactly what a Ruby lambda is.

The lambda method belongs to the Kernel module. Since Ruby 1.9 introduced an alternative syntax, a lambda can also be identified with the characters ->. So, the following two code blocks are equivalent:

succ = ->(x) { x + 1 }
succ = lambda { |x| x + 1 }

Another thing to note about lambdas is their arity, or how many arguments are required when they are called. Every lambda has a precise arity, which can be tested using the arity method as follows:

->(x) { x + 1 }.arity # => 1

There is much more that can be said about lambdas but I’ll leave that to others. For example, Chapter 6, Methods, Procs, Lambdas, and Closures within The Ruby Programming Language by David Flanagan and Yukihiro Matsumoto gives a thorough treatment despite the age of the book.

As a taste, let me quote:

Blocks are syntactic structures in Ruby; they are not objects, and cannot be manipulated as objects. It is possible, however, to create an object that represents a block. Depending on how the object is created, it is called a proc or a lambda. Procs have block-like behavior and lambdas have method-like behavior. Both, however, are instances of class Proc.

Rails Scopes

At the time of writing, the latest Rails version is 4.2.4. On the subject of Rails scopes it is worth reading what is said about them in the Rails guides.

It is also worth keeping in mind that Rails has undergone many changes in it’s history. Currently the Rails guides illustrate that this:

class Article < ActiveRecord::Base
  scope :published, -> { where(published: true) }
end

is exactly the same as:

class Article < ActiveRecord::Base
  def self.published
    where(published: true)
  end
end

Furthermore, the Rails Guides section about passing in arguments advises:

Using a class method is the preferred way to accept arguments for scopes.

In other words, this:

class Article < ActiveRecord::Base
  def self.created_before(time)
    where("created_at < ?", time)
  end
end

is preferable to:

class Article < ActiveRecord::Base
  scope :created_before, ->(time) { where("created_at < ?", time) }
end

If you look carefully and test the two styles, you will realise that the important part of the code is the where clause. So long as the scope or class method returns an object that is an ActiveRecord::Relation, it can be chained together with other scopes or class methods.

In essence, with Rails 4.2 there is no reason to use scopes together with lambdas in preference to class methods. It is a matter of personal preference.

So, why the emphasis on using scopes with lambdas?

To answer this we need to consider the history of Rails. It was around the time of version 2 that named scopes were introduced. They allowed the convenience of chaining scope calls together. Later, if my memory serves me correctly, in version 3, Arel was introduced. This reduced the importance of named scopes when it came to specifying a variety of conditions to return a collection of model objects.

Fast forward to today and, as the Rails Guides state, there is no need to use scopes with lambdas instead of their equivalent class methods, which are arguably easier to read. However, given that Rails has been around for over ten years now, there are lots of legacy Rails codebases, many of which contain a plethora of scopes. Also, there are plenty of seasoned Rails programmers who have formed the habit of using Rails scopes.

In Summary

Hopefully this post has done a better job of clarifying the use of lambdas in Rails scopes than my original fumbling reply during a conversation at last week’s Melbourne Ruby meetup.

Tags: rails ruby scopes lambdas | Comments (0)

Bundler and Disk Space

March 19th, 2015

Earlier this week I noticed that my MacBook Pro’s 256GB hard disk was 95% full, which prompted me to start investigating what I could remove in order to free up space.

ncdu

Having remembered that on a previous occasion a work colleague had suggested using ncdu, I started this very helpful tool and task-switched whilst waiting for it to finish.

When I delved into what ncdu had to show me about large files, I eventually made an interesting discovery.

After regaining some space by deleting some Apple Mail log files, I was surprised to find many git versions of some internal RubyGems that we use at work. Some of these are large. All of them are referred to in Gemfiles by their GitHub repositories, or in other words they are git referenced gems defined in the Gemfile like this:

gem 'blake-data-source', git: 'git@github.com:blake-education/blake-data-source.git', branch: 'develop'

The result was this:

That’s right. The gems for Ruby 2.1.2 were taking up 10.5GB of disk space! Looking closely, I could see that there were many old versions of large gems.

At this point it is worth pointing out that I was using rbenv and Bundler to manage my gems in an unsophisticated manner. This had unintended consequences as I will explain further.

Cleaning up old versions of gems

gem cleanup

One way of cleaning up old versions of gems is to use the gem cleanup command. However, whilst this will remove old versions of gems that have been tagged with version numbers, it won’t include git referenced gems in it’s sweep.

bundle clean

Another command that can help clean up old gem versions is bundle clean --force. This is definitely a helpful command but one to be used with caution.

In my case I had to be aware that, since this command would clean up gem versions unused in my directory, it would also clean up gems used by other projects using the same Ruby version.

bundle —path

Advice from my colleague Josh Kunzmann quickly allowed me to see the solution. That was to run bundle clean --force and then change to using the bundle install --path command, or bundle --path for short. As the documentation says, the --path option allows you to:

Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME). Bundler will remember this value for future installs on this machine

And, since I am in the habit of using bash aliases and tmuxinator, I am now using aliases like this to start project coding sessions:

alias mkp='bundle --path ~/.appgems/kpdotcom --clean && mux kp'

In this way I should be able to keep the disk space used by RubyGems under control. It also ensures that dependent gem versions are installed before I fire up tmuxinator.

Conclusion

The moral of the story is twofold:

  1. ncdu is a very useful tool for discovering large files on your hard disk
  2. bundle --path your/chosen/path --clean is a good way to ensure that old versions of git referenced gems do not accumulate

Tags: bundler rubygems ncdu ruby | Comments (1)

On Test Driven Development

September 14th, 2014

Recently I responded to a request for help with setting up a new machine on which to develop Rails applications.

A little while later I was pleased to hear that Rosie Williams had completed setting up her new Mac and was ready to continue developing the Rails app that Matt Allen had helped her get started with at a Rails Girls event.

As you can see from the Twitter exchange below, I also cheekily asked Rosie whether she had all her tests passing.

I didn’t expect that Rosie would have ventured down the TDD path yet but I guess I couldn’t resist asking the question. The value of automated testing is something I have long cared about.

Why are automated tests important?

Now I’m not one who always practices strict TDD. I don’t always start with a failing test and work towards enabling that test to pass. Sometimes I do but other times I find more value in experimenting with a solution in other ways, e.g. via a REPL or a browser, before writing an automated test.

And there are times that I don’t bother with automated tests at all. However, those situations are definitely in the minority.

If I am working on a production system that an organisation is dependent on for more than a brief period of time, I consider automated tests to be vital.

Why? The simple answer is that software needs to be malleable.

Developers need to be able to make changes to a software system to meet changing needs of business. To allow a software system to adapt to changing requirements, the design needs to be continually improved. Integral to such refactoring is a sufficiently comprehensive suite of automated tests. Without such tests there will be too great a risk of new defects being introduced.

An anecdote about refactoring

Recently I have been responding to various reports from users, all impacted by problems in a subsystem of a large Rails codebase.

It has been a classic case of defects caused by software that is far too complex for the essential job it was designed to do. To my eyes, it is begging to be refactored. To work with the code as it is now, it can take a disproportionate amount of time to debug a problem due to the challenge in deciphering what it is doing. It is clear that the internal design of this code needs to be improved so that it is easier for the next person to understand. So I intend to refactor this code in the near future.

Fighting software entropy

Like many things, software is prone to entropy over time. Without careful maintenance, it is likely to degrade as bandaid solutions are progressively applied.

Refactoring is a key part of enabling software to successfully adapt. Automated tests are crucial to refactoring.

Opinions about TDD

Unsurprisingly, there are differing views about TDD. Without going into depth here, I will allude to some interesting discussions between Martin Fowler, Kent Beck and David Heinemeier Hansson a few months ago, which I summarised in a talk I gave at a Sydney Ruby meetup in July.

Resources

I hope this post has been useful, particularly to newcomers to Rails development who may have been wondering what all the fuss is about TDD. There is much more to say about testing and refactoring but for now I’ll end this post by recommending:

Tags: testing tdd refactoring rails ruby | Comments (0)

Thanking the Australian Ruby Community

July 17th, 2013

It was during the recent Ruby Rogues episode about Community Hacks that the suggestion was made that we, as a programming community need more blog posts.

There is no doubt that the onslaught of Twitter has resulted in a proliferation of pithy comments that fit into 140 characters together with the inevitable exchanges between other Twitter users that follow. This is all fine in itself, very social and lots of fun. However, longer form, more thoughful blog posts have been somewhat of a casualty.

So I’ve decided to make my own attempt at rectifying this. In the spirit of the RR Community Hacks podcast, I want to thank a few people in the Australian Ruby community who have enriched my professional and social life over the last 6 or 7 years. Forgive me if I reminisce a little along the way.

A Community Journey

First Encounters

Having first explored Ruby in 2004 and stumbled across Rails the day DHH announced he had open-sourced it, my introduction to the Australian Ruby community came by chance at the Open Source Developers’ Conference in Melbourne in 2006. A colleague of mine at the time, Alan Green, was co-presenting a paper comparing Django and Rails with a fellow named Ben Askins.

Following the conference, Ben kindly introduced me to the Sydney Ruby community. He also organised the first Rails Camp in June 2007, which I attended. It goes without saying that I have much to thank Ben for.

The Sydney Ruby Scene

I recall, in the early days, it was people like Tim Lucas and Jason Crane who spearheaded the monthly Sydney Rails meetup, a forerunner of the event now affectionately known as “rorosyd”. Another person who actively supported the group’s online connections was Lachie Cox. Who else remembers the “number5” bot in the #roro IRC channel?

Then there was Matt Allen who, intriguingly in retrospect, had a not insignificant hand in helping me land my first Rails freelance gig back in late 2007. Little did “Matta” know it then, but he was putting in some early practice for his current role!

Rails Camps

I mentioned the first Rails Camp, which Ben Askins organised conveniently at Somersby, just up the road from where I live. Unfortunately I was unable to attend the second Rails Camp, held in late 2007 near Melbourne. However, I have certainly come to know and respect Pat Allan, the organiser of that camp. I think it is fair to say that Pat has established himself as the Rails Camp “champion”, spreading it to other parts of the globe including the UK, Denmark, Germany, USA, Poland and Spain. The only Rails Camp outside of Australia that I have been to was at Mt Cheeseman in New Zealand in 2012. Of course, Pat was there!

The uninitiated reader may wonder why I’m such a fan of Rails Camps. Maybe that’s the subject of another post. Suffice to say that, if you’re at all interested in Ruby and getting to know people in the Australian Ruby community in a fun-filled, self-organising environment – and learning along the way – come along the next Rails Camp!

Ruby Open Source

When I think of Australians who have contributed to open source Ruby, Pat Allan comes to mind again for his work on Thinking Sphinx as well as sharing his knowledge about Crafting Gems.

Others who have created useful, well-received Ruby gems include Justin French, for his work on Formtastic, and Pete Yandell, who created Machinist.

Pat, Justin and Pete are just three of many Australian Rubyists who have inspired me by their contribution to open source.

Ongoing Encouragement

I love the supportive nature of people in the Ruby community. Without wishing to make it sound like a cult whose members are a cut above other developers, I’m certainly grateful for the encouragement I’ve received from many quarters. Martin Stannard is an example of someone who has continued to encourage me over the last few years and I thank him for his support. Was it really as long ago as 2008 that we, together with Pat, Matt, Marcus Crafter, Dylan Egan and others were in Portland for RailsConf?

RubyConfAU

Being part of the organising crew for the first Australian Ruby conference was a highlight of my career. It wouldn’t have been possible without the help of Martin Stannard, Michael Koukoullis, Josh Price and Sebastian von Conrad, not to mention the awesome volunteers who ensured everything ran smoothly at the conference. The backing of Ruby Australia also enabled the conference organisation to proceed on a sounder footing. For this I am grateful to Richie Khoo and Pat Allan (again) for their hard work in establishing Ruby Australia.

Even better, Josh and others have stepped up to the plate to run the next RubyConfAU, in Sydney in February 2014.

The Future

A critical component of the success of any community is renewal and revitalisation. For example, whilst I convened Sydney Ruby meetups for a while, I’m grateful to Steven Ringo for taking over the baton during the last couple of years. And I’m sure he is grateful to Andrew Harvey, who is stepping into the role next month whilst Steven’s attention will be more focussed on the impending birth of another child.

We’re currently in a situation where demand for developers exceeds supply. Within the Ruby community, I’m heartened to see efforts to introduce more people to the skills and knowledge necessary to get them started.

Rails Girls is one movement that is introducing women to Rails. We are fortunate to have people such as Robert Postill, Nigel Rausch, Elle Meredith, and Andrew Harvey to thank for ensuring that events have taken place in Melbourne, Brisbane and Sydney this year. Also, the initiatives of Mikel Lindsaar in starting the Installfest and Development Hub events, as a way of getting new Rails developers started and accelerating their skill development, are to be commended.

In Conclusion

Of course, there are many more people who have inspired me along my journey so far. However, those above sprang most readily to mind when I pondered the question of who in Australia has inspired and helped me so far in my Ruby journey.

Thank you all!

Tags: community australia ruby | Comments (0)

Installing Ruby 1.8.7 with rbenv

March 9th, 2013

Having considered the move for quite a while, this evening I finally decided to migrate from RVM to rbenv. The tipping point came as I was freeing up space on my laptop’s hard disk and discovered that the .rvm directory was occupying 21G, which seemed rather excessive.

Having jettisoned RVM, installed rbenv and ruby-build, I set about installing various versions of Ruby.

Despite the fact that Ruby 2.0.0 has recently been released and Matz has strongly encouraged users to upgrade from 1.8.7, which is due for end of life this June, I still have one customer I need to support on 1.8.7 for the time being.

This brings me to the point of this post. Unlike later versions, I struck a couple of problems with installing 1.8.7 with rbenv, just as I had done recently with RVM.

The solution was to use configuration options to tell rbenv where to get readline and to not bother with installing tcl and tk:

$ CONFIGURE_OPTS="--with-readline-dir=$(brew --prefix readline) --without-tcl --without-tk" rbenv install 1.8.7-p371

Tags: rbenv ruby | Comments (0)

Anticipating RubyConf Austalia 2013

February 15th, 2013

We are on the home stretch!

Just over a year ago I made a commitment to ensure that the inaugural Australian Ruby programming conference would become a reality. Next week, in Melbourne, it will.

RubyConf Australia 2013 will kick off with a day of workshops on Wednesday before more than 350 delegates gather at the conference to hear speakers present a variety of Ruby-related talks on Thursday and Friday.

With less than a week to go, you may wonder why I have chosen to devote time to a blog post now. You’d think I would be flat out doing last minute things in preparation. Of course I am, but I guess I thought it would be therapeutic to spend a few minutes sharing my reflections about organising the conference.

I won’t go into exhaustive detail now but I do want to emphasise several factors which have underpinned the conference organisation. Without them, I doubt we would have got to where we are today without much more pain.

  • The establishment of Ruby Australia as a non-profit organisation to support the conference (and Rails Camps) was a crucial first step. This avoided individuals being liable and clearly marked the conference as being owned by the Australian Ruby community.
  • The partnership with YOW! has been invaluable. They have run very successful software development conferences in Australia for several years and it made sense to utilise their expertise.
  • A small core group of organisers has also worked well. I am indebted to Mike Koukoullis and Martin Stannard for their collaborative support. I think we’ve made a very effective team.
  • Having underlined the importance of the core organising group, it would be remiss of me not to acknowledge a host of others in the community who have helped, or will be helping, in different ways at various times. They know who they are.
  • Another point worth mentioning was the use of a GitHub repository for collecting and managing talk proposals. I liked it’s openness, it worked well and I would recommend it to other organisers of technical conferences.
  • Finally, we have been able to attract more than 15 overseas presenters and sell the tickets at a reasonable price only because of the generosity of our sponsors, whom we much appreciate.

That’s it for now. I’m not sure how insightful that was for you. It was somewhat cathartic for me but not as helpful as the drinks at the conference closing party will be.

Wish us luck!

Tags: ruby australia rubyconf_au ruby conferences | Comments (0)

Is TDD Enough?

June 11th, 2012

One thing that the Rails community prides itself on is that test-driven development (TDD) is widely employed. But is this sufficient to produce good quality code that stands the test of changing requirements over a long period of time?

In my recent roundup of Ruby resources, Sandi Metz is one author I recommended. In her excellent talk at the 2009 Gotham Ruby Conference, Sandi contested that TDD is not enough. Sandi’s talk, which concentrates on applying SOLID design principles in Ruby, is well worth listening to in its entirety.

2009 – Sandi Metz – SOLID Object-Oriented Design from Gotham Ruby Conference on Vimeo.

As Sandi explains, central to SOLID design is avoiding dependencies by striving for code that is:

  • loosely coupled
  • highly cohesive
  • easily composable
  • context independent

As she demonstrates applying these principles through refactoring a small Ruby application, Sandi shows that, if we want code to endure in a state that makes it fun to work with, we need to do more than use TDD. As Sandi refactors she emphasises that when we reach a point where the tests pass, we should not be satisfied. Nor should ensuring that the code is DRY be enough. Other questions that need to be asked about the class under test are:

  • Does it have one responsibility?
  • Does everything in it change at the same rate?
  • Does it depend on things that change less often than it does?

Only when the answer to all of these questions is “yes” should we move on.

I know these are questions I should ask myself more often. As Sandi stresses, “test driven development is good, but it’s not enough.”

Tags: testing design ruby | Comments (3)

Ruby Resources on my Radar

June 6th, 2012

There’s never enough time!

I’d love to have more time to make use of all the resources I have at my disposal to learn more about the Ruby programming language.

It is eight years since I first encountered Ruby and nearly five since I moved to using Ruby as my language of choice to earn a living. So I’ve collected many different resources during those years as I have progressed through my journey to hopefully become a more proficient practitioner of the language that Matz designed to make programming a happier experience.

Inspiration

Recently I gave a lightning talk at the Sydney Ruby meetup (a.k.a. rorosyd) inspired by the Ruby Rogues podcast. I love the format that Charles Max Wood et al use, particularly their “picks” at the end of the show. So I decided I’d give the podcast a plug, provide some picks of my own and then open it up to the audience to share their picks.

The experience set me thinking about all the wonderful resources now available to Ruby programmers – so many to choose from. I thought I’d take the time to share my viewpoint. Hopefully you’ll take away something useful.

First of all, here are the picks I chose to share at “rorosyd” and why I chose them.

Podcast: Ruby Rogues

Ever since I started listening to the Ruby Rogues podcast a few months ago I have found it compelling. Regular panelists Charles Max Wood, Avdi Grimm, Josh Susser, James Edward Gray II and David Brady always present a lively and entertaining podcast. When combined with the views of their guest, the discussion never fails to leave me with lessons learned and thoughts provoked.

Book: Objects on Rails – Avdi Grimm

Even though I’m still working my way through Avdi’s book I’ve read enough to know that I can thoroughly recommend his approach. As the title implies, Avdi encourages readers of Objects on Rails to go beyond blindly using Rails and think in terms of Ruby objects. His use of what he calls Exhibits to bridge the gap between views and models is exemplary.

Book: The Rails View – John Athayde and Bruce Williams

Although not strictly a Ruby book, it is one that I nevertheless thoroughly recommend to all Rails developers. The Rails View provides a long overdue, comprehensive coverage of the one part of the Rails MVC triad that has been often overlooked in the past. With the advent of the Rails 3.1 Asset Pipeline, this is a timely addition.

Screencasts: Railscasts Pro – Ryan Bates

For years Ryan Bates endeared himself to the Ruby on Rails community by providing free, informative, well prepared and presented Railscasts about various Rails topics on a weekly basis. Ryan manages to summarise the essence of his topics in 10 or 15 minutes per episode. Now he has launched Railscasts Pro, and at $9 per month I consider them a steal.

Github Ruby Style Guide

Whilst there are numerous resources about how to solve various problems with the Ruby language, the Github Ruby Style Guide provides an excellent guide to the nuances of the style with which Ruby code should be formatted.

Podcast: The Ruby Show

For several years I’ve been enjoying The Ruby Show, a weekly Ruby news podcast hosted by Peter Cooper, of Ruby Inside fame, and Jason Seifer. I like their informal style of banter during which they also manage to deliver a good coverage of what’s topical in the world of Ruby programming.

More Resources on my Radar

When I delved further into my library of Ruby resources, I found more excellent examples, some more thoroughly explored than others.

Articles: Practicing Ruby – Gregory Brown

I’ve found some gems of understanding about Ruby within the articles of Practicing Ruby, which Gregory Brown describes as “an eclectic journal for the dedicated hacker”. It certainly comes under the category of “Ruby resources I’d love to fully utilise if I had more time”. If you want to explore the nuances of programming with Ruby, I thoroughly recommend Practicing Ruby.

Book: Practical Object-Oriented Design in Ruby – Sandi Metz

In fact, it was within a Practicing Ruby article about SOLID Design Principles that I first came across the excellent work of Sandi Metz through a recommendation Gregory gave about a talk she gave at GoRuCo in 2009. Now Sandi is in the process of releasing her book, Practical Object-Oriented Design in Ruby. Sandi shows how to design Ruby classes so that programmers who use your code later will thank you.

Book: Eloquent Ruby – Russ Olsen

How could Ruby programmer who values craftsmanship and who has already read Russ Olsen’s work not be tempted by his book Eloquent Ruby? This book guides the reader through a series of rules of thumb about how to make the most of Ruby’s many facets. For more, see the book’s companion site.

Book: Metaprogramming Ruby – Paolo Perrotta

Want a thorough treatment of metaprogramming techniques in Ruby? Look no further than Paolo Perrotta’s book, Metaprogamming Ruby. It guides the reader through the fundamentals of metaprogramming before exploring the way it was used in the Rails 2.3 codebase. Also included are some useful appendices about common Ruby idioms and how DSLs overlap with metaprogramming.

Screencast: The Ruby 1.9 Walkthrough – Peter Cooper

At the time of writing I’m about half way through watching Peter Cooper’s detailed screencast about what’s new in Ruby 1.9. What’s really instructive is the tool that Peter uses throughout to show how snippets of Ruby code produce different results in different versions of Ruby, all as part of the same output. This is a superb way of demonstrating the improvements in Ruby 1.9. Obviously very well researched, The Ruby 1.9 Walkthrough is to be thoroughly recommended.

Some Old Favourites

Peepcode Screencasts – Geoffrey Grosenbach

I’m a self-confessed fan of Peepcode Screencasts. Whilst Peepcode now covers a broad range of technologies there are some excellent recent screencasts which focus on Ruby, such as the Play by Play episodes featuring Aaron Patterson and Jim Weirich.

Book: The Ruby Programming Language – David Flanagan & Yukihiro Matsumoto

Finally, if you want a definitive reference, The Ruby Programming Language provides a comprehensive yet concise coverage.

In Conclusion

The resources about the language have proliferated since 2001 when Dave Thomas and Andy Hunt helped spread Ruby beyond Japan through their book popularly known as The Pickaxe, which has been updated to cover Ruby 1.9.

Wherever you are along your journey with exploring programming in Ruby, I hope there is something in this list that you will find useful.

Tags: resources ruby | Comments (1)

Maintaining a Legacy Rails App

April 5th, 2011

Last night I deployed a new release of a Rails app.

Having deployed apps built with Rails 3 or at the very least Rails 2 apps using Bundler, the experience of deploying a Rails 2.3.5 app left me with a keen desire to at least bring this app up to Rails 2.3.11 with Bundler.

One of the delights of last night’s deployment was having to update RubyGems on the target machine. Usually this is as simple as:

gem update --system

That is, unless you are forced to upgrade to a specific, old release of RubyGems. Being at Rails 2.3.5 with this app, we were in this situation.

Speaking of “not exactly state of the art”, the version of Ruby on the target machine is Ruby Enterprise Edition 1.8.6.

Obviously, the preferred option would be to upgrade to Ruby 1.9.2 and Rails 3.0.5 forthwith.

However, it’s not my money that will be funding the upgrade. First steps first. I’m aiming for the following path:

  • Rails 2.3.11 with Bundler and latest compatible gems.
  • Ruby 1.9.2
  • Rails 3.0.5

Wish me luck!

Tags: legacy apps rubygems rails ruby | Comments (0)

Upgrading to Rails 3

February 27th, 2011

Introduction

It was long overdue.

Rails 3.0.5 is out and I’ve finally bitten the bullet and upgraded this site to Rails 3 and Ruby 1.9.2. The site had its genesis back in mid-2007 as I was preparing to start my own business. Since 2008 the codebase hasn’t received much love. Indeed, I have only published articles here in dribs and drabs over the last couple of years.

So, as I embarked on this upgrade, I was aware that it also represented an opportunity to clean up some of my code as well as update third party libraries.

What follows is a story of how the upgrade unfolded including some decisions I made along the way and some lessons I learned.

Ruby 1.9.2

My initial intention was to just upgrade the app to use Ruby 1.9.2 and attack the Rails 3 upgrade later. However, as I soon found out, getting the app to work on Ruby 1.9 wasn’t as easy as I had anticipated. Sure, using RVM it was easy to change to using Ruby 1.9.2 in development. I also chose to move to Bundler even though my intention was to stay at Rails 2.3 for now.

However, I quickly discovered that not all the plugins I was using had been upgraded to run on Ruby 1.9.

Syntax Highlighting Adventures

Back in 2008 when I implemented syntax code highlighting I chose to use the tm_syntax_highlighting plugin, which is based on Ultraviolet. Unfortunately, the original tm_syntax_highlighting plugin is not supported on Ruby 1.9. There is a gem derived from it that claims to support Ruby 1.9 but I failed to get this to work.

I had a look at the suggestions from Ryan Bates and, because I had been using a solution based on Ultraviolet, I considered using Harsh but soon found that it was not supported on Ruby 1.9.

At this point I decided to go the whole hog and upgrade to Rails 3. As for supporting syntax highlighting, I ended up switching to use CodeRay.

Rails 3 Here I Come

First point of call for anybody embarking on a Rails 3 upgrade has to be Jeremy McAnally’s Rails 3 Upgrade Handbook. This invaluable resource not only guides you through using the official “rails upgrade” tool but explains how to make the most of the improvements in Rails 3.

So I methodically worked my way through the upgrade to the point where I was able to start and use the Rails console. This was a real milestone but I still had much to do before I could consider my upgrade complete.

Time to jettison old plugins

When I attempted to get the app running via a browser it quickly became evident that it was high time I jettisoned some ancient plugins.

Chief of these was the acts_as_authenticated plugin. Yes, I did say ancient. I’m aware that Devise is a favoured authentication solution for Rails 3. However, having had success in other projects with Authlogic, I chose to use it in the interests of expediency.

Another old plugin that needed replacing was acts_as_taggable_on_steroids. The acts_as_taggable_on gem proved to be an effective replacement for this with minimal changes required.

The final old plugin to be jettisoned was akismetor, which I replaced with the Rakismet gem.

Some comments about testing

I haven’t said anything about automated tests to this point. That is quite simply because I haven’t touched them. I know I should but, since this is a relatively small app that really only affects me, I decided to bypass automated testing in favour of completing the upgrade quickly. Some may scold me for this decision but I couldn’t justify the effort to myself. I’ll come back and get the automated tests working again later.

Note: If this was a larger app for a customer I would be far less inclined to bypass the task of ensuring that the automated tests work before considering the upgrade complete.

Reflections

I’m glad I’ve taken the time to upgrade this app to Rails 3 and Ruby 1.9.2. It has given me the chance to:

  • replace old plugins with more recent gems;
  • take advantage of Bundler;
  • practice upgrading to Rails 3;
  • position the app for further code improvements courtesy of Rails 3 and Ruby 1.9.

And, of course, now I can say that I have upgraded an old Rails app to Rails 3!

Tags: rails ruby | Comments (1)

RVM, Bundler and Ruby Tracker

August 11th, 2010

Lightning Talk at rorosyd

Here are the slides from a lightning talk I gave at rorosyd last night. Having found RVM, Bundler and Ruby Tracker to be a useful set of tools this year, I thought I’d take the opportunity to share my experiences. And, as I mentioned during the talk, kudos to Mikel Lindsaar for his blog post earlier this year which alerted me to the power of creating a .rvmrc file.

Tags: rorosyd ruby tracker rvm bundler ruby | Comments (0)

Inspirations for a Ruby DSL

September 6th, 2009

Recently, during discussions with a client about reducing the amount of boilerplate coding that recurs from time to time in the project, the idea of developing a Domain Specific Language (DSL) arose. If you’re wondering what a DSL is, here is what Martin Fowler has to say. Or, you may prefer this cheeky piece from Dr Nic Williams.

I’ve been intrigued by DSLs for some time but not had the motivation to develop one until now.

In preparation, I’ve gathered a list of resources for writing a DSL in Ruby.

Tutorials

  • Russ Olsen’s two part article
  • Chapter 16 on DSLs in Russ Olsen’s “Design Patterns in Ruby” book
  • Mischa Fierer’s three part article about writing a clean Ruby DSL

Examples

I’m happy with that list of resources but if anyone has any other suggestions please feel free to comment.

My next challenge is to think about the problem domain and design an elegant syntax.

Tags: dsl ruby | Comments (0)

Impressed with Prawn for PDF Generation

April 5th, 2009

I’ve been aware of Prawn, the Ruby PDF generation library for some time. Today was the first occasion I had an opportunity to utilise it and I was delighted with how easy it was to use.

My Ruby application needed to generate some tabular PDF reports so I installed the prawn gem and, with a little help from the examples on the Prawn home page and the core and layout documentation, I was off and running.

An example of using prawn via a rake task follows:

require 'rubygems'
require 'prawn'
require 'prawn/layout'
namespace :report do
  desc "Generate top 10 points getters report"
  task :top10 => :environment do
    Prawn::Document.generate("reports/top10.pdf") do
      font "#{Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf"
      font_size 14
      text "Top 10 Points Getters"
      text " "
      # fetch two-dimensional array of data for the table
      data = Player.top10_data
      table data,
        :font_size  => 9,
        :position   => :center,
        :headers    => ["#", "Player", "Points"],
        :row_colors => ["ffffff", "eeeeee"]
    end
  end
end

Generating the report was then as simple as running:

rake report:top10

I’m looking forward to using other features of Prawn such as image embedding and content positioning. At the time of writing prawn itself is version 0.4.1 and prawn-layout is 0.1.0. Hopefully James Healy, an Australian noted as “instrumental to the forward development of the library”, is coming to Railscamp 5 next month. Then I can pick his brains about what other features are in the pipeline.

Tags: prawn pdf ruby | Comments (1)

Automated Testing with Ruby

December 8th, 2008

The fifth Australian Open Source Developers’ Conference was held last week in Sydney. In addition to helping organise the conference, I was fortunate enough to be one of the Ruby presenters.

View SlideShare presentation or Upload your own. (tags: osdc osdc2008au)

Naturally, these slides were designed to assist my presentation rather than contain all the content. Indeed, the inclusion of some of the slides may beg some questions so I thought it may be helpful to add some explanation here.

Reminiscing about Testing

Each of us programmers is on a specific journey, especially when it comes to testing. Early in my professional career I was taught how to unit test program modules written in PL/I. However, the drivers for those tests had to be written in Job Control Language (JCL) – an experience I am not in a hurry to repeat.

Many years later, having escaped from working on mainframes, I discovered JUnit. This was a fundamental tool in my early experience of test driven development and refactoring. When I began exploring Ruby and Rails, I was eventually introduced to autotest, which I considered another quantum leap forward in the realm of automated testing.

Testing Tools

In 25 minutes there was obviously a limit to the number of Ruby testing tools I could cover. So, having quickly explained the benefit of autotest and touched upon Test::Unit, I moved on to describe some tools that I have used in the last year.

RSpec

To make sure the audience was still awake, at this point I showed a cute photo of our family dog. My lame excuse was that he exhibits a wide range of behaviours and RSpec is all about specifying behaviour. My main example of using RSpec was for specifying a controller. This led on to a brief digression into consider what makes a good test and the use of mock objects to isolate unit tests and make them faster by avoiding unnecessary database I/O.

Integration Testing with Cucumber, Webrat and Selenium

I was pleased to be able to include Cucumber, Webrat and Selenium in my talk. It’s only fairly recently that I started using Cucumber in conjunction with Webrat or Selenium and I’m impressed. As Mike Koukoullis showed in his subsequent talk, developing with Cucumber is a very powerful approach, which fosters clear description of intent before development of any feature.

Speaking of other talks, Alister Scott used a lightning talk to share his enthusiasm for Watir, which looks like a good alternative to Selenium.

Test Data with Machinist

After briefly relating the motivation for developing alternatives to relying on fixtures for test data, I described Machinist, an elegant tool recently developed by Pete Yandell. When used in conjunction with Sham, Machinist provides a neat way of generating “blueprints” that can be used in Cucumber steps.

Other Tools

I briefly mentioned JavaScript unit testing tools that are the subject of a blog post by Dr Nic as well as touching upon Shoulda, which is well written up by Dave Thomas.

Philosophy

To round out my talk, I thought it was important to offer a few philosophical thoughts. In a nutshell my view is that, whilst it is important to remember that automated testing is just one of many error removal approaches, we can all benefit from investing in automated testing.

In my case, as well as practicing using these tools, I’m also looking forward to reading the upcoming title The RSpec Book by David Chelimsky and others.

Tags: testing osdc ruby conferences | Comments (0)