Ruby SuperStruct: enhanced version of the standard Ruby Struct

A few months ago I created a custom class to enhance the base Ruby Struct object. What I needed for my Whois library was the ability to create a new instance from a Hash.

Loser = Struct.new(:id, :name)
Winner = SuperStruct.new(:id, :name)

# The default Struct accepts up to N arguments
# where N is the total number of elements defined in the Struct.
Loser.new(:id => "1", :name => "John Doe")
# => #<struct Loser id={:name=>"John Doe", :id=>"1"}, name=nil>

Winner.new(:id => "1", :name => "John Doe")
# => #<struct Winner id="1", name="John Doe">

Because the first argument is mapped to the :id element, the Hash is stored as value for the id attribute.

In a standard Ruby Struct I have to map each Hash value to the specific position in the Struct, loosing the flexibility of passing a Hash with optional keys.

hash = { :name => "John Doe" }

Loser.new(hash)
# => #<struct Loser id={:name=>"John Doe"}, name=nil>
Loser.new(nil, hash[:name])
# => #<struct Loser id=nil, name="John Doe">

Winner.new(hash)
# => #<struct Winner id=nil, name="John Doe">

Also, I'd like to be able to pass a block to the initialize method and yield on self.

Loser.new do |c|
  c.name = "John Doe"
end
# => #<struct Loser id=nil, name=nil>
# Name is not set

Winner.new do |c|
  c.name = "John Doe"
end
# => #<struct Winner id=nil, name="John Doe">
# Hurra! Name is set!

I called it RubyStruct. It was created for the Ruby Whois, but ultimately I found myself using it quite often in my projects and I decided to package it in a single file along with a basic test suite.

Here's the library.