Guest User

Untitled

a guest
May 27th, 2018
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.02 KB | None | 0 0
  1. class Module
  2. class Overloader
  3. EVERYTHING = Object.new
  4.  
  5. class << (ANYTHING = Object.new)
  6. def ===(object); true; end
  7. end
  8.  
  9. def initialize
  10. @functions = {}
  11. end
  12.  
  13. def run_for(object, *args, &block_arg)
  14. args << block_arg if block_arg
  15.  
  16. @functions.each do |args_expr, block|
  17. i, match = 0, true
  18. args_expr.each do |expr|
  19. if expr === args[i]
  20. i += 1
  21. elsif expr == EVERYTHING
  22. i = args.size
  23. else
  24. match = false
  25. end
  26. end
  27.  
  28. next if i < args.size unless i == (args.size - 1) and block_arg
  29. next unless match
  30. return object.instance_exec(*args, &block)
  31. end
  32.  
  33. raise ArgumentError, "Given arguments aren't valid."
  34. end
  35.  
  36. def when_given(*args, &block)
  37. @functions[args] = block
  38. end
  39.  
  40. def method_missing(symbol, *args, &block)
  41. meth = symbol.to_s
  42. case meth
  43. when /^(\w+)_or_(\w+)$/
  44. begin
  45. objects = [$1, $2].map { |i| self.send(i) }
  46. rescue NoMethodError
  47. super
  48. end
  49.  
  50. o = Object.new
  51. meta_class = (class << o; self; end)
  52. meta_class.class_eval do
  53. define_method(:===) do |other|
  54. objects.any? { |e| e === other }
  55. end
  56. end
  57.  
  58. o
  59. when /^an?_(\w+)$/
  60. begin
  61. Object.const_get($1.capitalize)
  62. rescue NameError
  63. super
  64. end
  65. else
  66. super
  67. end
  68. end
  69.  
  70. def anything
  71. ANYTHING
  72. end
  73.  
  74. def everything
  75. EVERYTHING
  76. end
  77.  
  78. def nothing
  79. nil
  80. end
  81. end
  82.  
  83. def overload(method, &block)
  84. overloader = Overloader.new
  85. overloader.instance_eval(&block)
  86.  
  87. define_method(method) do |*args, &block|
  88. overloader.run_for(self, *args, &block)
  89. end
  90. end
  91. end
  92.  
  93. module Kernel
  94. overload :foo do
  95. when_given(a_string, an_integer) do |string, num|
  96. puts string * num
  97. end
  98.  
  99. when_given(a_string_or_an_integer) do |obj|
  100. p obj
  101. end
  102. end
  103. end
  104.  
  105. foo "a", 3
  106. foo 42
  107. foo "abc"
  108. foo 1.5
Add Comment
Please, Sign In to add comment