Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on May 5th, 2012  |  syntax: None  |  size: 1.28 KB  |  hits: 13  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. module Kernel
  2.   def match_class?( class_spec )
  3.     case class_spec
  4.     when Class
  5.       # A plain value
  6.       return false unless self.is_a? class_spec
  7.     when Hash
  8.       # When we expect a keyed enumerator
  9.       return false unless self.method(:each)
  10.       # A hashlike each will return two values
  11.       self.each do |(k,v)|
  12.         key_type = class_spec.keys.select { |s| k.is_a? s }
  13.         # Pass if any of the possible spec types fit the data.
  14.         return false unless key_type.any? { |s| v.match_class?( class_spec[s] ) }
  15.       end
  16.     when Array
  17.       # When we expect an enumerator
  18.       return false unless self.method(:each)
  19.       # Treat the array of specs as a repeatable sequence
  20.       # Make sure the data matches each spec in turn
  21.       spec_list = class_spec.each.cycle
  22.       self.each do |i|
  23.         next_spec = spec_list.next
  24.         return false unless i.match_class?( next_spec )
  25.       end
  26.     end
  27.     true
  28.   end
  29. end
  30.      
  31. # Examples:
  32.  
  33. # Simple, and overkill. Should have used is_a?
  34. 1.match_class? Integer
  35.  
  36. # Slightly more complex...
  37. [ 1, 2, 3 ].match_class? [ Integer ]
  38.  
  39. # Much more complex...
  40. [ { :foo => 1 }, { :foo => 2 } ].match_class?( [ { Symbol => Integer } ] )
  41.  
  42. # And to prove it works, this will fail:
  43. [ { :foo => 1 }, { :foo => 2.0 } ].match_class?( [ { Symbol => Integer } ] )