Ruby: define a class with

This card will show you a cool way to define a class using Archive .
A common usecase for Structs are temporary data structures which just hold state and don't provide behaviour. In many cases you could use a simple hash as a data structure instead. However, a Struct provides you with a nice constructor, attribute accessors and complains if you try to access undefined attributes. Structs are easy to compare (by attributes). A struct gives meaning to the data.


Structs are great but sometimes there are arguments against their usage:

  • Hashes are incredibly fast. If you have to handle lots of data it may be better to use hashes for performance reasons, even if the readability of the code suffers compared to using structs.
  • Also, if the struct is used not only within a module / class but throughout the whole application it may be better to use an ActiveType::Object Archive (or something similar) because other developers will expect the objects to behave like they are used to from ActiveRecord.

Define a class and create objects:

UserPreview =, :email, :name)

u =, '', 'Hans Peter')
=> #<struct UserPreview gid=1, email="", name="Hans Peter">

access attributes:

=> 1
=> "Hans Peter"
=> "Hans Peter"
=> "Hans Peter"
=> "Hans Peter"

=> [1, "", "Hans Peter"]
=> {:gid=>1, :email=>"", :name=>"Hans Peter"}
NoMethodError: undefined method `foo' for #<UserPreview:0x00565427e1aa38>

compare objects:, '', 'Hans Peter') ==, '', 'Hans Peter')
    => true

More examples

Define Struct with methods:

Address =, :city, :country) do
  def to_s
    each.inject { |concat, attr| concat += "\n#{attr}" }

a ='Bahnhofstr. 1', '86150 Augsburg', 'Germany')
puts a
Bahnhofstr. 1
86150 Augsburg

Initialize with keyword arguments

If you prefer to create objects that feel more like ActiveRecord classes you could use the :keyword_init argument.
This will allow you to make the new method a bit more verbose and independent of argument order:

Customer =, :address, keyword_init: true) "Dave", address: "123 Main")
=> #<struct Customer name="Dave", address="123 Main">

Anti patterns

You might sometimes see that a class inherits from a stuct like this:

class Address <, :city, :country) 

Address =, :city, :country) do

This should be avoided as it creates an extra anonymous class that will never be used ( see the docs Archive ).

Further reading

Daniel Stra├čner over 5 years ago
This website uses short-lived cookies to improve usability.
Accept or learn more