public
Last active

ruby method patterns

  • Download Gist
method_patterns.rb
Ruby
1 2 3 4 5 6 7 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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
# Usage
# class Foo
# include MethodPatterns
#
# defp :greet, check(:nil?) do |obj|
# p 'HA! NIL!'
# end
#
# defp :greet, match_any do |obj|
# p 'Hey, Object!'
# end
# end
#
# foo = Foo.new
# foo.greet(nil) => 'HA! NIL!'
# foo.greet(1) => 'Hey, Object!'
 
module MethodPatterns
MethodPattern = Struct.new(:condition, :method)
PatternError = Class.new(StandardError)
 
module ClassMethods
def check (sym)
->(e) { sym.to_proc.call(e) }
end
 
def avoid (sym)
->(e) { !sym.to_proc.call(e) }
end
 
def match_any
->(e) { true }
end
 
def defp (method, cond, &block)
@method_patterns ||= {}
(@method_patterns[method] ||= []) << MethodPattern.new(cond, Proc.new(&block))
end
 
attr_reader :method_patterns
end
 
def execute_method_pattern (patterns, *args)
patterns.each do |mp|
return mp.method.call(*args) if mp.condition.call(*args)
end
 
raise MethodPatternError.new 'unmatched pattern'
end
 
def method_missing (method, *args, &block)
cache = self.class.method_patterns
 
if cache.has_key?(method)
execute_method_pattern(cache[method], *args)
else
super
end
end
 
def self.included (base)
base.extend(ClassMethods)
end
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.