Skip to content

Commit

Permalink
Add memoization to methods when they are added
Browse files Browse the repository at this point in the history
  • Loading branch information
dkubb committed Aug 11, 2014
1 parent 4fe4144 commit af31be4
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 10 deletions.
5 changes: 1 addition & 4 deletions lib/adamantium.rb
Expand Up @@ -47,10 +47,7 @@ def self.included(descendant)
descendant.class_eval do
include Memoizable
extend ModuleMethods
if instance_of?(Class)
extend ClassMethods
memoize(:hash, :inspect, :to_s)
end
extend ClassMethods if instance_of?(Class)
end
end
private_class_method :included
Expand Down
15 changes: 15 additions & 0 deletions lib/adamantium/module_methods.rb
Expand Up @@ -4,6 +4,8 @@ module Adamantium

# Methods mixed in to adamantium modules
module ModuleMethods
MEMOIZE_METHODS = [:hash, :inspect, :to_s].freeze
RECURSION_GUARD = IceNine::RecursionGuard::ObjectSet.new

# Return default deep freezer
#
Expand Down Expand Up @@ -47,6 +49,19 @@ def included(descendant)
descendant.module_eval { include Adamantium }
end

# Hook called when method is added
#
# @param [Symbol] method_name
#
# @return [undefined]
#
# @api private
def method_added(method_name)
RECURSION_GUARD.guard(self) do
memoize(method_name) if MEMOIZE_METHODS.include?(method_name)
end
end

# Memoize the named method
#
# @param [Symbol] method_name
Expand Down
14 changes: 12 additions & 2 deletions spec/unit/adamantium/hash_spec.rb
Expand Up @@ -6,8 +6,18 @@
describe Adamantium, '#hash' do
subject { object.hash }

let(:object) { described_class.new }
let(:described_class) { AdamantiumSpecs::Object }
let(:object) { described_class.new }

let(:described_class) do
Class.new(AdamantiumSpecs::Object) do
FIXNUM_MAX = 2**(0.size * 8 - 2) - 1
FIXNUM_MIN = -2**(0.size * 8 - 2)

def hash
Random.rand(FIXNUM_MIN..FIXNUM_MAX)
end
end
end

it_behaves_like 'a hash method'
end
11 changes: 9 additions & 2 deletions spec/unit/adamantium/inspect_spec.rb
Expand Up @@ -6,8 +6,15 @@
describe Adamantium, '#inspect' do
subject { object.inspect }

let(:object) { described_class.new }
let(:described_class) { AdamantiumSpecs::Object }
let(:object) { described_class.new }

let(:described_class) do
Class.new(AdamantiumSpecs::Object) do
def inspect
rand.to_s
end
end
end

it_behaves_like 'an idempotent method'
end
11 changes: 9 additions & 2 deletions spec/unit/adamantium/to_s_spec.rb
Expand Up @@ -6,8 +6,15 @@
describe Adamantium, '#to_s' do
subject { object.to_s }

let(:object) { described_class.new }
let(:described_class) { AdamantiumSpecs::Object }
let(:object) { described_class.new }

let(:described_class) do
Class.new(AdamantiumSpecs::Object) do
def to_s
rand.to_s
end
end
end

it_behaves_like 'an idempotent method'
end

0 comments on commit af31be4

Please sign in to comment.