adamantium icon indicating copy to clipboard operation
adamantium copied to clipboard

Create immutable objects

adamantium

Create immutable objects with ease.

Gem Version Build Status Dependency Status Code Climate Coverage Status

This is a small standalone gem featuring a module extracted from axiom. It allows you to make objects immutable in a simple, unobtrusive way.

Examples

require 'adamantium'
require 'securerandom'

class Example
  # Inclusion of Adamantium defaults to deep freeze behavior
  # of constructor and memoizer

  include Adamantium

  # Instance and attributes (ivars) are frozen per default
  # Example:
  #
  # object = Example.new
  # object.frozen?           # => true
  # object.attribute.frozen? # => true
  #
  def initialize
    @attribute = "foo bar"
  end
  attr_reader :attribute

  # Memoized method with deeply frozen value (default)
  # Example:
  #
  # object = Example.new
  # object.random => ["abcdef"]
  # object.random => ["abcdef"]
  # object.random.frozen? => true
  # object.random[0].frozen? => true
  #
  def random
    [SecureRandom.hex(6)]
  end
  memoize :random

  # Memoized method with non frozen value
  # Example:
  #
  # object = Example.new
  # object.buffer         # => <StringIO:abcdef>
  # object.buffer         # => <StringIO:abcdef>
  # object.buffer.frozen? # => false
  #
  def buffer
    StringIO.new
  end
  memoize :buffer, freezer: :noop

  # Memoized method with shallow frozen value
  # Example:
  #
  # object = Example.new
  # object.random2 => ["abcdef"]
  # object.random2 => ["abcdef"]
  # object.random2.frozen? => true
  # object.random2[0].frozen? => false
  #
  def random2
    [SecureRandom.hex(6)]
  end
  memoize :random2, freezer: :flat

  # Transform method derives changed instances without
  # calling the constructor
  # Example:
  #
  # object = Example.new
  # object.random => ["abcdef"]
  # update = object.edit "baz quux"
  # update.random => ["abcdef"]
  # update.attribute => "baz quux"
  #
  def edit(attribute)
    transform do
      @attribute = attribute
    end
  end
end

class FlatExample
  # Inclusion of Adamantium::Flat defaults to shallow frozen
  # behavior for memoizer and constructor

  include Adamantium::Flat

  # Instance is frozen but attribute is not
  # Example:
  #
  # object = FlatExample.new
  # object.frozen?           # => true
  # object.attribute.frozen? # => false
  #
  def initialize
    @attribute = "foo bar"
  end
  attr_reader :attribute

  # Memoized method with flat frozen value (default with Adamantium::Flat)
  # Example:
  #
  # object = Example.new
  # object.random => ["abcdef"]
  # object.random => ["abcdef"]
  # object.random.frozen? => true
  # object.random[0].frozen? => false
  #
  def random
    [SecureRandom.hex(6)]
  end
  memoize :random
end

Credits

Contributing

See CONTRIBUTING.md for details.

Copyright

Copyright © 2012-2014 Dan Kubb. See LICENSE for details.