lib/adamantium/module_methods.rb in adamantium-0.1.0 vs lib/adamantium/module_methods.rb in adamantium-0.2.0

- old
+ new

@@ -3,29 +3,15 @@ module Adamantium # Methods mixed in to adamantium modules module ModuleMethods - # Hook called when module is included - # - # @param [Module] mod - # the module including ModuleMethods - # - # @return [self] - # - # @api private - def included(mod) - Adamantium.included(mod) - self - end - # Return default deep freezer # # @return [Freezer::Deep] # # @api private - # def freezer Freezer::Deep end # Memoize a list of methods @@ -44,137 +30,37 @@ method_freezer = Freezer.parse(options) || freezer methods.each { |method| memoize_method(method, method_freezer) } self end - # Test if an instance method is memoized + private + + # Hook called when module is included # - # @example - # class Foo - # include Adamantium + # @param [Module] descendant + # the module including ModuleMethods # - # def bar - # end - # memoize :bar + # @return [self] # - # end - # - # Foo.memoized?(:bar) # true - # Foo.memoized?(:baz) # false, does not care if method acutally exists - # - # @param [Symbol] name - # - # @return [true] - # if method is memoized - # - # @return [false] - # otherwise - # # @api private - # - def memoized?(name) - memoized_methods.key?(name) + def included(descendant) + super + descendant.module_eval { include Adamantium } end - # Return original instance method - # - # @example - # - # class Foo - # include Adamantium - # - # def bar - # end - # memoize :bar - # - # end - # - # Foo.original_instance_method(:bar) #=> UnboundMethod, where source_location still points to original! - # - # @param [Symbol] name - # - # @return [UnboundMethod] - # if method was memoized before - # - # @raise [ArgumentError] - # otherwise - # - # @api public - # - def original_instance_method(name) - memoized_methods[name] - end - - private - # Memoize the named method # - # @param [#to_s] method_name + # @param [Symbol] method_name # a method name to memoize # @param [#call] freezer - # a freezer for memoized values + # a callable object to freeze the value # # @return [undefined] # # @api private def memoize_method(method_name, freezer) - method = instance_method(method_name) - if method.arity.nonzero? - raise ArgumentError, 'Cannot memoize method with nonzero arity' - end - memoized_methods[method_name] = method - visibility = method_visibility(method_name) - define_memoize_method(method, freezer) - send(visibility, method_name) + memoized_methods[method_name] = Memoizable::MethodBuilder + .new(self, method_name, freezer).call end - # Return original method registry - # - # @return [Hash<Symbol, UnboundMethod>] - # - # @api private - # - def memoized_methods - @memoized_methods ||= ThreadSafe::Hash.new do |_, name| - raise ArgumentError, "No method #{name.inspect} was memoized" - end - end - - # Define a memoized method that delegates to the original method - # - # @param [UnboundMethod] method - # the method to memoize - # @param [#call] freezer - # a freezer for memoized values - # - # @return [undefined] - # - # @api private - def define_memoize_method(method, freezer) - method_name = method.name.to_sym - undef_method(method_name) - define_method(method_name) do || - memory.fetch(method_name) do - value = method.bind(self).call - frozen = freezer.call(value) - store_memory(method_name, frozen) - end - end - end - - # Return the method visibility of a method - # - # @param [String, Symbol] method - # the name of the method - # - # @return [Symbol] - # - # @api private - def method_visibility(method) - if private_method_defined?(method) then :private - elsif protected_method_defined?(method) then :protected - else :public - end - end - - end # module ModuleMethods -end # module Adamantium + end # ModuleMethods +end # Adamantium