Explicit, block-level memoization for your Ruby projects, for when @foo ||= bar
isn't good enough.
When might you reach for MemoPad? When your memoized result could be falsey (since they'd always evaluate on the ||=
) or if you need to memoize a different result based on method arguments or other values.
MemoPad differs from other popular gems (like memoist or memery) primarily in how you memoize your result. Those tools abstract the memoization at a method level, by way of a memoize
class method, adding new methods to your objects (like the unmemoized method definitions), and getting in the way of tools like show-source
.
MemoPad avoids those frictions by trading the convenience of memoize :foo
with a more explicit declaration of what to memoize and where. Objects which include this module gain a #memo_pad
instance method which you can use to mememoize the result of any block to a given name (conventionally the method's name) and an optional set of arguments which should memoize distinct values.
See the Usage section below for an example class taking advantage of MemoPad.
Install the gem and add to the application's Gemfile by executing:
$ bundle add memo_pad
If bundler is not being used to manage dependencies, install the gem by executing:
$ gem install memo_pad
- First,
include MemoPad
in your class. - Then use
memo_pad.fetch(name, *args) do; end
to memoize the result of the block. - There is no step 3.
class Foo
include MemoPad
def expensive_method
memo_pad.fetch(:expensive_method) do
# Do some expensive work here
end
end
def expensive_method_with_arguments(foo, bar: nil)
memo_pad.fetch(:expensive_method, foo, bar) do
# Do expensive work here, respecting the values of `foo` and `bar`
end
end
def complex_memoization
first_part = memo_pad.fetch(:complex_memoization_first) do
# Some independent expensive work
end
# Maybe some other unmemoized work
memo_pad.fetch(:complex_memoization_second, first_part) do
# Some other expensive work, respecting the value of `first_part`
end
end
end
You can directly write a memo, if needed, with #write
. It has nearly the same signature as #fetch
, the name and optional list of arguments, with the addition of the value:
keyword argument to supply the value to write to the memo.
def precache_things(things)
things.each do |thing|
memo_pad.write(:has_thing?, thing, value: true)
end
end
You can also flush the whole of the cache on an instance.
foo.memo_pad.clear
After checking out the repo, run bin/setup
to install dependencies. Then, run rake test
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and the created tag, and push the .gem
file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/dribbble/memo_pad. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
The gem is available as open source under the terms of the MIT License.
Everyone interacting in the MemoPad project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.