Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache built-in query methods of immutable object #25

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,29 @@ class FlatExample
end
```

## Usage with equalizer

Adamanitum may be used with [equalizer](https://www.github.com/dkubb/equalizer)
as long as equalizer is included into the class first, eg:

```ruby
class Foo
include Equalizer.new(:foo)
include Adamantium
end
```

Another, less common form is to include all the modules in a single line. It is
important to note that ruby includes the modules in reverse order, starting
with the last module and working backwards, eg:

```ruby
class Foo
# equalizer will be mixed in first, then adamantium
include Adamantium, Equalizer.new(:foo)
end
```

## Credits

* Dan Kubb ([dkubb](https://github.com/dkubb))
Expand Down
2 changes: 1 addition & 1 deletion config/flog.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
threshold: 15.0
threshold: 16.3
15 changes: 15 additions & 0 deletions lib/adamantium/module_methods.rb
Original file line number Diff line number Diff line change
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
23 changes: 23 additions & 0 deletions spec/unit/adamantium/hash_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# encoding: utf-8

require 'spec_helper'
require File.expand_path('../fixtures/classes', __FILE__)

describe Adamantium, '#hash' do
subject { object.hash }

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
20 changes: 20 additions & 0 deletions spec/unit/adamantium/inspect_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# encoding: utf-8

require 'spec_helper'
require File.expand_path('../fixtures/classes', __FILE__)

describe Adamantium, '#inspect' do
subject { object.inspect }

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
20 changes: 20 additions & 0 deletions spec/unit/adamantium/to_s_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# encoding: utf-8

require 'spec_helper'
require File.expand_path('../fixtures/classes', __FILE__)

describe Adamantium, '#to_s' do
subject { object.to_s }

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