ruby-talk:192757 reminded me of SuperStruct.
I was going to reply with a pointer to that library, but I realized that the usual
class MyClass<Struct.new(:a,:b)def initialize(*a)super# stuffendend
idiom and SuperStruct still left an important part of the solution space uncovered.
When you inherit from a Struct, the resulting class doesn't use plain instance
variables, so you're forced to use the accessors. SuperStruct addresses that
while emulating Struct quite closely, and also introduces OpenStruct-like
features, so you get hash access with numeric, String and Symbol keys, #members, #to_a, pretty printing... But what if you don't need all that?
I'm guessing the OP would have wanted to do (at least that's what I wanted):
class Foo<InitializedClass.new(:a,:b,:c)def initialize(*a)super@c||=10# this is how we manage default valuesenddef bara+b*cendendFoo.new(1,2,3).bar# => 7
And while we're at it, why not get named arguments for free too?
Foo.new(:a=>1,:b=>2).bar# => 21
This (and a few additional features) takes 56 lines in my first implementation, including #instance_exec, which I already wrote about.
Inheritance
One thing neither Struct nor SuperStruct can do is create a class derived
from an existing one. Well, of course module inclusion is but another form of
inheritance (and multiple too), but some times you might want the real thing,
with matz's blessing.
Say you have
class Bazdef initialize(foo,bar)@foo=a@bar=bendend
and want to create a subclass with a number of attributes, but you also need
to be able to run Baz#initialize. If we were just subclassing manually,
super(whatever)
would do, but then there's no automatic accessors nor named arguments. Is it
possible at all to get both at once?