Module: Dom::Node
- Included in:
- CodeObject::Base, Document::Document, NoDoc
- Defined in:
- lib/dom/node.rb
Overview
including Class should set 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.
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`. Returns `nil? , if no matching child was found.
123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/dom/node.rb', line 123 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
-
Last Childnode i.e. “.foo” -> Append node as child
-
absolute path i.e. “Foo” -> delegate path resolution to Dom.root
-
relative path i.e. “.bar.foo”
-
if there is a matching child for first element, delegate adding to this node
-
create NoDoc node and delegate rest to this NoDoc
-
258 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 |
# File 'lib/dom/node.rb', line 258 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`
101 102 103 |
# File 'lib/dom/node.rb', line 101 def children @children end |
#each_child(&block) ⇒ Object
Iterates recursivly over all children of this node and applies ‘block` to them
229 230 231 232 233 234 |
# File 'lib/dom/node.rb', line 229 def each_child(&block) @children.values.each do |child| yield(child) child.each_child(&block) end end |
#find(path) ⇒ Object
Alias for bracket-access
138 139 140 |
# File 'lib/dom/node.rb', line 138 def find(path) self[path] end |
#has_children? ⇒ Boolean
Returns if the current node is a leaf or not.
146 147 148 |
# File 'lib/dom/node.rb', line 146 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.
312 313 314 |
# File 'lib/dom/node.rb', line 312 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.
92 93 94 95 |
# File 'lib/dom/node.rb', line 92 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.
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 |
# File 'lib/dom/node.rb', line 341 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.
324 325 326 |
# File 'lib/dom/node.rb', line 324 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
194 195 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 |
# File 'lib/dom/node.rb', line 194 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`.
153 154 155 156 |
# File 'lib/dom/node.rb', line 153 def siblings return nil if parent.nil? @parent.children end |