Design Patterns Made Trivial with Ruby
February 5th, 2007
Today I (again) experienced one of those moments I felt like hugging Ruby, if it was an organic being (wait.. it isn’t?).
I wanted a cleaner way to handle file paths compared to treating them as just strings with appropriate methods, so I wanted to make a new class `FilePath` which would support all methods that `String` class does. I also wanted to use delegation instead of inheritance due to semantic difference – I don’t think file paths are congruent to strings; however, representations of file paths are often strings.
Using Ruby’s built-in `DelegateClass` it was a snap. Adding ability to concatenate paths so that I don’t have to care about platform-dependent ways of encoding path separators was trivial due to `File.join`. Then I also needed a method which would return full path to given file relative to source referencing the file. So I ended up with the simple class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
require 'delegate' class FilePath < DelegateClass(String) def initialize(base, *args) super String.new( args.length > 0? File.join(base, args) : base ) end def +(path) File.join(self, path) end def rel_to_src_file make_new File.expand_path(File.join(File.dirname(__FILE__), self)) end private def make_new(obj) FilePath.new(obj) end end puts FilePath.new('basedir') puts FilePath.new('basedir', 'subdir') puts FilePath.new('basedir', 'subdir') + 'subsubdir' puts FilePath.new('basedir', 'subdir') + FilePath.new('subsubdir') puts FilePath.new('basedir').gsub('base', 'root') |
All this in just 20 lines of code, and it’s not a hack either. The point here is that design patterns are often so simple in Ruby that the whole name design pattern starts to feel like having too much grandeur in it.

Leave a Reply