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.