Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
key_struct gem
Ruby
tag: v0.2.0

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib
spec
.gitignore
Gemfile
LICENSE
README.rdoc
Rakefile
key_struct.gemspec

README.rdoc

key_struct

Defines KeyStruct, which acts the same as ruby's Struct but the struct's initializer takes keyword args (using a hash, rails-style). Use it to define a class via:

Name = KeyStruct[:first, :last]

or as an anonymous base class for your own enhanced struct:

class Name < KeyStruct[:first, :last]
  def to_s
    "#{@last}, #{@first}"
  end
end

Then you can create an instance of the class using keywords for the parameters:

name = Name.new(:first => "Jack", :last => "Ripper")

and you have the usal readers and writers

name.first            # --> "Jack"
name.last             # --> "Ripper"
name.last = "Sprat"
name.last             # --> "Sprat"
name.to_s             # --> "Sprat, Jack" for the enhanced class example

Readers, Writers, and Instance Variables

As per above, the normal behavior is to get readers and writers. But, by analogy with attr_reader vs attr_accessor, you can choose whether you want read/write or just read:

Writeable = KeyStruct.accesor(:first, :last)      # aliased as KeyStruct[]
Readonly = KeyStruct.reader(:first, :last)        # class has readers but not writers

The analogy is not just skin deep: KeyStruct actually uses attr_accessor or attr_reader to define the accessors for the generated class. This means that you also get the corresponding instance variables:

name.instance_variable_get("@last") # --> "Sprat"
name.instance_variable_set("@last", "Sparrow")
name.last             # --> "Sparrow"

The instance variables can be useful of course when using KeyStruct to define an anonymous base class for your own classes, as shown for the to_s example above.

(This is one way that KeyStruct differs from ruby's built-in Struct: built-in Struct does not define instance variables.)

Default values

If you leave off a keyword when instantiating, normally the member value is nil:

name = Name.new(:first => "Jack")
name.last             # --> nil

But when you define the class you can specify defaults that will be filled in by the class initializer. For example:

Name = KeyStruct[:first, :last => "Doe"]

name = Name.new(:first => "John")
name.first            # --> "John"
name.last             # --> "Doe"

name = Name.new(:first => "John", :last => "Deere")
name.first            # --> "John"
name.last             # --> "Deere"

Argument Checking

The struct initializer checks for invalid arguments:

name = Name.new(:this_is_a_typo => "Xavier")  # --> raises ArgumentError

Comparison

KeyStruct classes define the == operator, which returns true iff all corresponding struct members are equal (likewise via ==)

Name.new(:first => "John", :last => "Doe") == Name.new(:first => "John", :last => "Doe")    # --> true
Name.new(:first => "John", :last => "Doe") == Name.new(:first => "Jane", :last => "Doe")    # --> false

As a convenience when a well-defined ordering is needed, KeyStruct classes defines the <=> operator and includes the Comparable module. The <=> operator applies <=> to the coresponding struct members sequentially, returning the first that is non-0. The comparison is performed in the order the keys were listed in the class definition, so the first key is the primary comparison key, and so on down the line. Thus:

Name = KeyStruct[:first, :last]
Name.new(:first => "Abigail", :last => "Zither") <=> Name.new(:first => "Zenobia", :last => "Aardvark")           # --> -1

LastFirst = KeyStruct[:last, :first]
LastFirst.new(:first => "Abigail", :last => "Zither") <=> LastFirst.new(:first => "Zenobia", :last => "Aardvark") # --> +1

Converting to a hash

KeyStruct classes define a to_hash method that returns a hash containing all members and their values:

Name.new(:first => "Jack", :last => "Ripper").to_hash # --> {:first => "Jack", :last => "Ripper")

Installation

Install via:

% gem install key_struct

or in your Gemfile:

gem "key_struct"

Versions

Requires ruby >= 1.9.2. (Has been tested on MRI 1.9.2 and MRI 1.9.3)

History

Release Notes:

  • 0.2.0 - Introduced <=> and to_hash

  • 0.1.0 - Introduced ==

  • 0.0.1 - Initial version

Past: There was some discussion around this idea in this thread: www.ruby-forum.com/topic/138124 in 2008.

Future: I hope that this gem will be obviated in future versions of ruby.

Note on Patches/Pull Requests

  • Fork the project.

  • Make your feature addition or bug fix.

  • Add tests for it. Make sure that the coverage report (generated automatically when you run rspec) is at 100%

  • Send me a pull request.

Copyright

Released under the MIT License. See LICENSE for details.

Something went wrong with that request. Please try again.