Skip to content

Instantly share code, notes, and snippets.

Created July 19, 2011 01:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/21e3aed658edd7b0f785 to your computer and use it in GitHub Desktop.
Save anonymous/21e3aed658edd7b0f785 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# http://clojure.org/runtime_polymorphism
=begin
(defmulti encounter (fn [x y] [(:Species x) (:Species y)]))
(defmethod encounter [:Bunny :Lion] [b l] :run-away)
(defmethod encounter [:Lion :Bunny] [l b] :eat)
(defmethod encounter [:Lion :Lion] [l1 l2] :fight)
(defmethod encounter [:Bunny :Bunny] [b1 b2] :mate)
(def b1 {:Species :Bunny :other :stuff})
(def b2 {:Species :Bunny :other :stuff})
(def l1 {:Species :Lion :other :stuff})
(def l2 {:Species :Lion :other :stuff})
(encounter b1 b2)
-> :mate
(encounter b1 l1)
-> :run-away
(encounter l1 b1)
-> :eat
(encounter l1 l2)
-> :fight
=end
class DefMulti
def initialize &block
@dispatcher = block
@methods = []
end
def defmethod pattern, &block
@methods << [pattern,block]
end
def dispatch *args
_pattern = @dispatcher.call *args
@methods.each do |pattern,method|
return method.call *args if _pattern == pattern
end
end
end
encounter = DefMulti.new { |x,y| [x[:Species],y[:Species]] }
encounter.defmethod([:Bunny,:Lion]){|b,l| :run_away }
encounter.defmethod([:Lion,:Bunny]){|l,b| :eat }
encounter.defmethod([:Lion,:Lion]){|l1,l2| :fight }
encounter.defmethod([:Bunny,:Bunny]){|b1,b2| :mate }
b1={:Species => :Bunny, :other => :stuff}
b2={:Species => :Bunny, :other => :stuff}
l1={:Species => :Lion, :other => :stuff}
l2={:Species => :Lion, :other => :stuff}
puts encounter.dispatch b1, b2
puts encounter.dispatch b1, l1
puts encounter.dispatch l1, b1
puts encounter.dispatch l1, l2
=begin
# Output
mate
run_away
eat
fight
=end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment