Module: Metasploit::Model::Visitation::Visit::ClassMethods

Defined in:
lib/metasploit/model/visitation/visit.rb

Overview

Adds #visit DSL to class to declare visitors.

Instance Method Summary collapse

Instance Method Details

#visit(*module_names) {|node| ... } ⇒ Array<Metasploit::Model::Visitation::Visitor>

Defines how to visit a node with one or more Module#names in its Module#ancestors.

Parameters:

  • module_names (Array<String>)

    Names of class/module to be visited with block.

Yields:

  • (node)

    Block instance_exec'd on instance of the class #visit was called.

Yield Parameters:

  • node (Object)

Returns:

Raises:


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/metasploit/model/visitation/visit.rb', line 17

def visit(*module_names, &block)
  if module_names.empty?
    raise ArgumentError,
          "At least one Modul#name must be passed to #{__method__} so the visitor(s) knows which Modules " \
                "it/they can visit."
  end

  module_names.collect do |module_name|
    visitor = Metasploit::Model::Visitation::Visitor.new(
        :module_name => module_name,
        :parent => self,
        &block
    )
    visitor.valid!

    visitor_by_module_name[visitor.module_name] = visitor
  end
end

#visitor(klass) ⇒ Metasploit::Model::Visitation::Visitor

Visitor for klass or one of its Class#ancestors.

Returns:

Raises:

  • (TypeError)

    if there is not visitor for klass or one of its ancestors.


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/metasploit/model/visitation/visit.rb', line 40

def visitor(klass)
  visitor = visitor_by_module[klass]

  unless visitor
    klass.ancestors.each do |mod|
      visitor = visitor_by_module[mod]

      unless visitor
        visitor = visitor_by_module_name[mod.name]
      end

      if visitor
        visitor_by_module[klass] = visitor

        break
      end
    end
  end

  unless visitor
    raise TypeError,
          "No visitor that handles #{klass} or " \
                "any of its ancestors (#{klass.ancestors.map(&:name).to_sentence})"
  end

  visitor
end

#visitor_by_moduleHash{Class => Metasploit::Model::Visitation::Visitor}

Allows visitors to be looked up by Module instead of Module#name.

Returns:


71
72
73
# File 'lib/metasploit/model/visitation/visit.rb', line 71

def visitor_by_module
  @visitor_by_module ||= {}
end

#visitor_by_module_nameHash{String => Metasploit::Model::Visitation::Visitor}

Maps Module#name passed to #visit through :module_name to the Metasploit::Model::Visitation::Visitor with the Module#name as Metasploit::Model::Visitation::Visitor#module_name.

Returns:


80
81
82
# File 'lib/metasploit/model/visitation/visit.rb', line 80

def visitor_by_module_name
  @visitor_by_module_name ||= {}
end