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.