Memorium

Toolkit for creating convenient classes with lazy calculations. Provides method memoization, declarative attribute initialization, and attribute validation.

Installation

Add to your Gemfile:

gem "memorium"

Or install directly:

gem install memorium

Usage

Method Memoization (memo)

Cache the result of a method so it's computed only once:

class Calculator
  memo def heavy_computation
    sleep 2
    42
  end
end

calc = Calculator.new
calc.heavy_computation # => 42 (takes 2 seconds)
calc.heavy_computation # => 42 (instant, cached)

Inline syntax

memo def result
  expensive_call
end

Block syntax

memo
def result
  expensive_call
end

Access levels

Control visibility of the memoized method:

class Example
  memo def private_writer
    compute
  end, writer: :private

  memo writer: :private
  def private_writer
    compute
  end
end

Writer

You can also generate a writer to reset the memoized value:

class Example
  memo def value
    rand(100)
  end, writer: :public
end

obj = Example.new
obj.value # => 42
obj.value = 999
obj.value # => 999

Attribute Initialization (initialize_attr)

Declaratively define attributes with auto-generated initialize:

class User
  initialize_attr :name
  initialize_attr :email, required: :not_nil?
  initialize_attr :age,  required: :nil?
end

user = User.new(name: "Alice", email: "alice@example.com")
user.name  # => "Alice"
user.email # => "alice@example.com"
user.age   # => nil

With validation

class User
  initialize_attr :name, required: :not_nil?
  initialize_attr :email, required: :not_nil?
  initialize_attr :role,  required: :nil?
end

User.new(name: "Bob", email: "bob@example.com")
User.new(name: nil, email: "bob@example.com")
# => raises Memorium::AttributeRequired: Attribute `name` must be not_nil: nil

Attribute Validation (require_attr)

Validate attribute values at runtime:

class User
  initialize_attr :name, required: :not_nil?

  memo def name_caps = require_attr(:name).upcase
end

user = User.new(name: "alice")
user.name_caps # => "ALICE"

Available predicates:

  • :nil? — value must be nil
  • :not_nil? — value must not be nil
  • :not_empty? — value must not be empty
  • Any method name as a predicate (e.g., :zero?, :positive?)
  • Custom Proc: require_attr(:name, by: ->(v) { v.size > 2 })

Configuration

# By default, nil values are also memoized
Memorium.memoize_nil_values = true

# Disable nil memoization (nil will be recomputed each time)
Memorium.memoize_nil_values = false

Development

After checking out the repo, run bin/setup to install dependencies. Then run rake spec to run the tests.

bin/setup
rake spec

You can also run bin/console for an interactive prompt.

Contributing

Bug reports and pull requests are welcome at https://github.com/gem-forge/memorium.