shinzui (owner)

Fork Of

Revisions

gist: 176062 Download_button fork
public
Public Clone URL: git://gist.github.com/176062.git
Embed All Files: show embed
dispatcher.rb #
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
class Object
  def send_through(object, *args)
    object.dispatcher_for(self).call(self, *args)
  end
end
 
module Dispatcher
  class DispatcherNotFound < StandardError; end
 
  def self.extended(klass)
    klass.class_eval { @dispatchers = {} }
  end
 
  def for(kind, &block)
    @dispatchers[kind] = block
  end
 
  def dispatcher_for(object)
    return @dispatchers[object.class] ||= begin
      klass = object.class
      until klass == Object
        if @dispatchers.key?(klass)
          return @dispatchers[object.class] = @dispatchers[klass]
        end
        klass = klass.superclass
      end
 
      raise DispatcherNotFound, "No #{self} dispatcher for #{object.class}"
    end
  end
end
example.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
module Camelize
  extend Dispatcher
end
 
Camelize.for(String) do |string|
  string.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
end
 
Camelize.for(Object) do |object|
  ""
end
 
p "hello_hello".send_through(Camelize)
p nil.send_through(Camelize)