Method: Hash.method_added

Defined in:
lib/y_support/core_ext/hash/misc.rb

.method_added(sym) ⇒ Object

This kludge method guards against overwriting of the #slice method by ActiveSupport.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/y_support/core_ext/hash/misc.rb', line 8

def method_added( sym )
  if sym == :slice then
    # Unless it is our method, overwrite it.
    unless instance_method( sym ).source_location.include? 'y_support'
      # Let's now make a cache of this very method being called
      ma = singleton_class.instance_method :method_added
      # Let's remove the :method_added hook, or otherwise infinite recursion
      # would ensue.
      singleton_class.class_exec { remove_method :method_added }
      # And let's redefine the +:slice+ method now:
      warn "Warning: Attempt to redefine Hash##{sym} occured, reverting." if YSupport::DEBUG

      class_exec do
        # A bit like Array#slice, but only takes 1 argument, which is either
        # a Range, or an Array, and returns the selection of the hash for
        # the keys that match the range or are present in the array.
        # 
        define_method sym do |matcher|
          self.class[ case matcher
                      when Array then select { |k, _| matcher.include? k }
                      else select { |k, _| matcher === k } end ]
        end
      end

      # Finally, let's bind the +:method_added+ method to self again.
      singleton_class.class_exec do
        define_method :method_added do |sym| ma.bind( self ).call( sym ) end
      end
    end
  end
end