The first chapter of Understanding Computation does a whirlwind tour of Ruby programming - syntax, control structures, etc. One of the constructs the author calls out is the
Struct class. I've always used it like this:
That is, I'd use the
Struct constructor as a factory and assign the result to a constant. Then, if I needed to, I'd reopen the class that had just been created in order to add methods.
The example in the book does it a different way:
This creates an anonymous
Struct, uses it as a superclass, assigns it to a constant, and reopens the new class all in one fell swoop. I poked around various gems and this seems like a pretty common approach - for example,
Unicorn::App::Inetd::CatBody does this, and so does
The latter approach does result in more noise in the ancestor chain:
Struct.new returns an anonymous subclass of
Struct, and that subclass hasn't been assigned to a constant, so Ruby has to synthesize a
to_s value from the type and object id. You could get around that using the two-arg constructor, but that creates the new class as a constant in the class
Struct, which is a little weird:
Sometimes I see code create
Struct subclasses using the
class keyword without adding methods; for example from
Is there a reason to do the above rather than
OpenEvent = Struct.new(nil)?
Edit: Bruno Michel noted that the
Struct constructor also accepts a block:
This is a nice technique because it results in a clean ancestor chain.
Edit 2: Tom Stuart (the author of 'Understanding Computation') pointed out this great writeup on Structs by James Edward Grey II where he explains why he's using Structs in the way he does. Definitely worth a read, especially with Ara Howard weighing in with a comment about his
Thanks to Thomas Olausson for reviewing this post!