Creates struct-like classes (that can build value objects) that do not have setters and also have better constructors than Ruby's built-in Struct.
This is highly useful for creating presenters, non-database-related models, or other quick and dirty classes in your application. Instead of using a Hash or OpenStruct, you can create a bit more clarity around your types by using ImmutableStruct, which is almost as convenient.
Add to your Gemfile:
gem'immutable-struct'Then install:
bundle install
If not using bundler, just use RubyGems:
gem install immutable-struct
Person=ImmutableStruct.new(:name,:age,:job,:active?,[:addresses])dodefminor?age < 18endendp=Person.new(name: "Dave",# name will be 'Dave'age: 40,# age will be 40# job is omitted, so will be nilactive: true)# active and active? will be true# addresses is omitted, but since we've selected# Array coercion, it'll be []p.name# => "Dave"p.age# => 40p.active?# => truep.minor?# => falsep.addresses# => []p2=Person.new(name: "Dave",age: 40,active: true)p == p2# => truep.eql?(p2)# => trueSimilarPerson=ImmutableStruct.new(:name,:age,:job,:active?,[:addresses])sp=SimilarPerson.new(name: "Dave",age: 40,active: true)p == sp# => false # Different class leads to inequalitynew_person=p.merge(name: "Other Dave",age: 41)# returns a new object with merged attributesnew_person.name# => "Other Dave"new_person.age# => 41new_person.active?# => trueYou can coerce values into struct types by using the from method. This is similar to Ruby's conversion functions, e.g. Integer("1").
dave=Person.from(p)dave.equal?(p)# => true (object equality)daveish=Person.from(dave.to_h)daveish.equal?(dave)# => falsedaveish == dave# => trueYou can treat the interior of the block as a normal class definition with the exception of setting constants. Use const_set to scope constants as-expected.
Point=ImmutableStruct.new(:x,:y)doconst_set(:ZERO,0)ONE_HUNDRED=100endPoint::ZERO# => 0
::ONE_HUNDRED# => 100
::ZERO# => NameError: uninitialized constant ZERO