Class: Visitor::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/visitor/base.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.add_accept_method!(*args) ⇒ Object



9
10
11
12
13
14
15
16
17
18
# File 'lib/visitor/base.rb', line 9

def add_accept_method! *args
  name, options = parse_accept_args(args)
  klasses = Array(options[:to] || Object)
  visitor_klass = self
  klasses.each do |klass|
    klass.send :define_method, name do
      visitor_klass.new.visit(self)
    end
  end
end

.parse_accept_args(args) ⇒ Object



24
25
26
27
28
# File 'lib/visitor/base.rb', line 24

def parse_accept_args(args)
  options = if args.last.is_a? Hash then args.pop else {} end
  name = args.first || self.name.gsub(/Visitor$/, '').gsub(/.+([A-Z])/, "_\1").downcase
  return name, options
end

.to_class_name(duck) ⇒ Object



20
21
22
# File 'lib/visitor/base.rb', line 20

def to_class_name(duck)
  if duck.respond_to? :name then duck.name else duck end
end

.visitor_for(*klasses, &block) ⇒ Object



3
4
5
6
7
# File 'lib/visitor/base.rb', line 3

def visitor_for *klasses, &block
  klasses.each do |klass|
    define_method(:"visit_#{to_class_name(klass)}", block)
  end
end

Instance Method Details

#visit(thing) ⇒ Object



31
32
33
34
35
36
37
38
39
# File 'lib/visitor/base.rb', line 31

def visit thing
  thing.class.ancestors.each do |ancestor|
    method_name = :"visit_#{ancestor.name}"
    next unless respond_to? method_name
    return send method_name, thing
  end

  raise "Can't handle #{thing.class}"
end