Module: Dom::Node
- Included in:
- CodeObject::Base, Document::Document, NoDoc
- Defined in:
- lib/dom/node.rb
Overview
including Class should implement instance-variable @name
Node can be seen as an aspect or feature of another Object. Therefore it can be mixed in to add node-functionality to a class. Such functionality is used by code-objects and documents.
Instance Variables
The following instance-variables will be set while including Dom::Node into your class:
-
‘@name` (should be already set in your including class)
-
‘@parent`
-
‘@children`
Constant Summary collapse
- NS_SEP_STRING =
'.'
- NS_SEP =
/#{Regexp.escape(NS_SEP_STRING)}/
- NODENAME =
/[0-9a-zA-Z$_]+/
- LEAF =
/^#{NS_SEP}(?<name>#{NODENAME})$/
- ABSOLUTE =
/^(?<first>#{NODENAME})(?<rest>(#{NS_SEP}#{NODENAME})*)$/
- RELATIVE =
/^#{NS_SEP}(?<first>#{NODENAME})(?<rest>(#{NS_SEP}#{NODENAME})*)$/
Initialization collapse
-
#initialize ⇒ Object
The ‘constructor’ of Node.
Traversing collapse
-
#[](path) ⇒ Object
Get’s the child of this node, which is identified by ‘path`.
-
#children ⇒ Hash<Symbol, Dom::Node>
Returns all immediately associated children of this ‘node`.
-
#each_child(&block) ⇒ Object
Iterates recursivly over all children of this node and applies ‘block` to them.
-
#find(path) ⇒ Object
Alias for bracket-access.
-
#has_children? ⇒ Boolean
Returns if the current node is a leaf or not.
-
#parent ⇒ Dom::Node
‘node.parent` returns the parent node, if there is one.
-
#parents ⇒ Array<Dom::Node>
searches all parents recursivly and returns an array, starting with the highest order parent (excluding the root) and ending with the immediate parent.
-
#resolve(nodename) ⇒ Dom::Node?
Resolves ‘nodename` in the current context and tries to find a matching Node.
-
#siblings ⇒ Array<Dom::Node>?
Finds all siblings of the current node.
Manipulation collapse
-
#add_node(*args) ⇒ Object
There are three different cases 1.
Name- and Path-Handling collapse
-
#namespace ⇒ String
Like #qualified_name it finds the absolute path.
-
#print_tree ⇒ nil
Generates a text-output on console, representing the subtree-structure of the current node.
-
#qualified_name ⇒ String
The **Qualified Name** equals the **Absolute Path** starting from the root-node of the Dom.
Instance Method Details
#[](childname) ⇒ Dom::Node #[](path) ⇒ Dom::Node
Get’s the child of this node, which is identified by ‘path`
124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/dom/node.rb', line 124 def [](path) return @children[path] if path.is_a? Symbol return @children[path.to_sym] if path.split(NS_SEP_STRING).size == 1 path = path.split(NS_SEP_STRING) child = @children[path.shift.to_sym] return nil if child.nil? # decend recursive child[path.join(NS_SEP_STRING)] end |
#add_node(path, node) ⇒ Object #add_node(node) ⇒ Object
There are three different cases
1. Last Childnode i.e. ".foo"
-> Append node as child
2. absolute path i.e. "Foo"
-> delegate path resolution to Dom.root
3. relative path i.e. ".bar.foo"
a. if there is a matching child for first element, delegate
adding to this node
b. create NoDoc node and delegate rest to this NoDoc
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 |
# File 'lib/dom/node.rb', line 259 def add_node(*args) # Grabbing right overload if args.count == 2 node = args[1] path = args[0] elsif args.count == 1 node = args[0] path = '.'+node.name raise NoPathGiven.new("#{node} has no path.") if path.nil? else raise ArgumentError.new "Wrong number of arguments #{args.count} for 1 or 2" end leaf = LEAF.match path if leaf # node found, lets insert it add_child(leaf[:name], node) else matches = RELATIVE.match path if matches name = matches[:first].to_s # node not found, what to do? add_child(name, NoDoc.new(name)) if self[name].nil? # everything fixed, continue with rest self[name].add_node(matches[:rest], node) else # has to be an absolute path or something totally strange raise WrongPath.new(path) unless ABSOLUTE.match path # begin at top, if absolute Dom.add_node '.' + path, node end end end |
#children ⇒ Hash<Symbol, Dom::Node>
Returns all immediately associated children of this ‘node`
103 104 105 |
# File 'lib/dom/node.rb', line 103 def children @children end |
#each_child(&block) ⇒ Object
Iterates recursivly over all children of this node and applies ‘block` to them
231 232 233 234 235 236 |
# File 'lib/dom/node.rb', line 231 def each_child(&block) @children.values.each do |child| yield(child) child.each_child(&block) end end |
#find(path) ⇒ Object
Alias for bracket-access
139 140 141 |
# File 'lib/dom/node.rb', line 139 def find(path) self[path] end |
#has_children? ⇒ Boolean
Returns if the current node is a leaf or not.
147 148 149 |
# File 'lib/dom/node.rb', line 147 def has_children? not (@children.nil? or @children.size == 0) end |
#initialize ⇒ Object
60 61 62 63 64 |
# File 'lib/dom/node.rb', line 60 def initialize super @children, @parent = {}, nil @name ||= "" # should be written by including class end |
#namespace ⇒ String
Like #qualified_name it finds the absolute path. But in contrast to qualified_name it will not include the current node.
313 314 315 |
# File 'lib/dom/node.rb', line 313 def namespace parents.map{|p| p.name}.join NS_SEP_STRING end |
#parents ⇒ Array<Dom::Node>
searches all parents recursivly and returns an array, starting with the highest order parent (excluding the Dom.root) and ending with the
immediate parent.
94 95 96 97 |
# File 'lib/dom/node.rb', line 94 def parents return [] if @parent.nil? or @parent.parent.nil? @parent.parents << @parent end |
#print_tree ⇒ nil
Generates a text-output on console, representing the subtree-structure of the current node. The current node is not being printed.
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 |
# File 'lib/dom/node.rb', line 342 def print_tree # Because parent = nil and parent = Dom.root are handled the same at #parents # we need to make a difference here if @parent.nil? level = 0 else level = parents.count + 1 end @children.each do |name, child| puts "#{" " * level}-#{name.to_s}#{' (NoDoc)' if child.is_a? NoDoc}" child.print_tree end nil end |
#qualified_name ⇒ String
The **Qualified Name** equals the **Absolute Path** starting from the root-node of the Dom.
325 326 327 |
# File 'lib/dom/node.rb', line 325 def qualified_name parents.push(self).map{|p| p.name}.join NS_SEP_STRING end |
#resolve(nodename) ⇒ Dom::Node?
Resolves ‘nodename` in the current context and tries to find a matching Dom::Node. If `nodename` is not the current name and further cannot be found in the list of children the parent will be asked for resolution.
Given the following example, each query (except ‘.log`) can be resolved without ambiguity.
# -Core
# -extend
# -extensions
# -logger
# -log
# -properties
# -log
Dom[:Core][:logger].resolve '.log'
#=> #<CodeObject::Function:log @parent=logger @children=[]>
Dom[:Core][:logger][:log].resolve '.log'
#=> #<CodeObject::Function:log @parent=logger @children=[]>
Dom[:Core][:logger][:log].resolve '.logger'
#=> #<CodeObject::Object:logger @parent=Core @children=[]>
Dom[:Core].resolve '.log'
#=> #<CodeObject::Function:log @parent=Core @children=[]>
Dom[:Core][:properties].resolve '.log'
#=> #<CodeObject::Function:extend @parent=Core @children=[]>
Dom[:Core][:logger].resolve 'foo'
#=> nil
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/dom/node.rb', line 196 def resolve(nodename) return self if nodename == @name return nil if @children.nil? and @parent.nil? path = RELATIVE.match(nodename) if path first, rest = path.captures # we did find the first part in our list of children if not @children.nil? and @children.has_key? first.to_sym # we have to continue our search if rest != "" @children[first.to_sym].resolve rest # Finish else @children[first.to_sym] end else @parent.resolve nodename unless @parent.nil? end # It's absolute? elsif ABSOLUTE.match nodename Dom.root.find nodename end end |
#siblings ⇒ Array<Dom::Node>?
Finds all siblings of the current node. If there is no parent, it will return ‘nil`.
155 156 157 158 |
# File 'lib/dom/node.rb', line 155 def siblings return nil if parent.nil? @parent.children end |