Guest User

Untitled

a guest
Jul 17th, 2018
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.36 KB | None | 0 0
  1. module RuleBook
  2. def RuleBook.add_rules(object, instance_or_class, rules)
  3. instance_or_class = instance_or_class.to_s.downcase.strip.to_sym
  4. raise(ArgumentError, "'instance_or_class' must equal :instance or :class") unless [:instance, :class].include?(instance_or_class)
  5. raise(ArgumentError, "'rules' must be a Hash") unless rules.is_a?(Hash)
  6.  
  7. unless object.instance_variable_get(:@_rulebook_initiated) # Class instance variable. Not class variable. Not instance variable. Is confusing.
  8. object.instance_variable_set(:@_rulebook_initiated, true)
  9. object.instance_variable_set(:@_rulebook, {:instance=>{}, :class=>{}}) # @_rulebook is actually two rulebooks, instance and class
  10. end
  11.  
  12. case instance_or_class
  13. when :instance then object.instance_eval { include RuleBook::InstanceMethods }
  14. when :class then object.instance_eval { extend RuleBook::ClassMethods }
  15. end
  16.  
  17. object.instance_variable_get(:@_rulebook)[instance_or_class].merge!(rules)
  18. end
  19.  
  20. def RuleBook.find_and_call_rule_if_exists(object, instance_or_class, method, *args, &blk)
  21. instance_or_class = instance_or_class.to_s.downcase.strip.to_sym
  22. raise(ArgumentError, "'instance_or_class' must equal :instance or :class") unless [:instance, :class].include?(instance_or_class)
  23. where_to_find_rulebook = instance_or_class == :instance ? object.class : object
  24. rulebook = where_to_find_rulebook.instance_variable_get(:@_rulebook)[instance_or_class]
  25. matching_rules = rulebook.find_all{ |a| regex = a.first; !!regex.match(method.to_s) }
  26.  
  27. unless matching_rules.empty?
  28. last_result = nil
  29.  
  30. matching_rules.each do |regex, method_assigned_to_rule|
  31. match = regex.match(method)
  32. last_result = object.send(method_assigned_to_rule, *match.captures, *args)
  33. end
  34.  
  35. last_result
  36. else
  37. raise(NoMethodError, "method '#{method}' does not exist.")
  38. end
  39. end
  40.  
  41. module InstanceMethods
  42. def method_missing(method, *args, &blk)
  43. RuleBook.find_and_call_rule_if_exists(self, :instance, method, *args, &blk)
  44. end
  45. end
  46.  
  47. module ClassMethods
  48. def method_missing(method, *args, &blk)
  49. RuleBook.find_and_call_rule_if_exists(self, :class, method, *args, &blk)
  50. end
  51. end
  52. end
  53.  
  54. class Module
  55. def instance_rule(rules)
  56. RuleBook.add_rules(self, :instance, rules)
  57. end
  58. def class_rule(rules)
  59. RuleBook.add_rules(self, :class, rules)
  60. end
  61. end
Add Comment
Please, Sign In to add comment