I don't like hacky Ruby class definitions

I’ve seen a class definition pattern in Ruby (generally not Rails) and finally found a use for it while working on project Euler problems. It looks like this:

1
2
class MatrixPosition < Struct.new(:row, :column)
end

This gives me a 2-line class definition that has attributes row and column. This appears to be equivalent to:

1
2
3
4
5
6
7
8
class MatrixPosition
  attr_accessor :row, :column

  def initialize(row=nil, column=nil)
    @row=row
    @column=column
  end
end

So this seems like a great line-reducer for defining simple classes. However, loading the same file more than once produces this error:

1
2
3
4
5
6
7
8
9
10
11
1.9.3-p286 :011 > require './prob15'
 => true
1.9.3-p286 :012 > SolutionGrid.new 5
NameError: undefined local variable or method `populate_grid' for #<struct SolutionGrid size=5>

# ...

# Here we use load since 'require' does nothing when a file has been
# required previously
1.9.3-p286 :013 > load './prob15.rb'
TypeError: superclass mismatch for class SolutionGrid

The explanation has been made elsewhere already, so I won’t go into detail here.

This weird error message is a side effect of the Struct inheritance shortcut, and it’s enough to blow itself out of my toolkit. I thought I might care too much about code purity, but I think it’s sufficient to say that someone maintaining spork didn’t approve of this either. The latter way of declaring the class is more verbose, but it’s less error-prone so I’ll take that instead.