Class: Rattler::Util::Node

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/rattler/util/node.rb

Overview

A Node is a node that can be used as-is to compose tree structures or as a base class for user-defined node types. It is the base class used for all tree structures in the Rattler framework.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeNode #initialize(child...) ⇒ Node #initialize(attribute...) ⇒ Node #initialize(child..., attribute...) ⇒ Node

Returns a new instance of Node.

Overloads:

  • #initializeNode

    Create a Node object with no children or attributes.

  • #initialize(child...) ⇒ Node

    Create a Node object with children and no attributes.

  • #initialize(attribute...) ⇒ Node

    Create a Node object with attributes and no children.

  • #initialize(child..., attribute...) ⇒ Node

    Create a Node object with children and attributes.



31
32
33
34
# File 'lib/rattler/util/node.rb', line 31

def initialize(*args)
  @attrs = args.last.respond_to?(:to_hash) ? args.pop : {}
  @__children__ = args
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *args) ⇒ Object

Allow attributes to be accessed as methods.



151
152
153
# File 'lib/rattler/util/node.rb', line 151

def method_missing(symbol, *args)
  (args.empty? and attrs.has_key?(symbol)) ? attrs[symbol] : super
end

Class Method Details

.Node.[]Node .Node.[](child...) ⇒ Node .Node.[](attribute...) ⇒ Node .Node.[](child..., attribute...) ⇒ Node



19
20
21
# File 'lib/rattler/util/node.rb', line 19

def self.[](*args)
  self.new(*args)
end

Instance Method Details

#==(other) ⇒ Boolean

Return true if the node is equal to other. Normally this means other is an instance of the same class or a subclass and has equal children and attributes.



135
136
137
138
139
# File 'lib/rattler/util/node.rb', line 135

def ==(other) #:nodoc:

  self.class === other and
  other.can_equal?(self) and
  self.same_contents?(other)
end

#[](index) ⇒ Object #[](start, length) ⇒ Array #[](range) ⇒ Array

Access the node’s children as if the node were an array of its children.



126
127
128
# File 'lib/rattler/util/node.rb', line 126

def [](*args)
  children[*args]
end

#attrsHash

Return a the node’s attributes.



64
65
66
# File 'lib/rattler/util/node.rb', line 64

def attrs
  @attrs ||= {}
end

#can_equal?(other) ⇒ Boolean



161
162
163
# File 'lib/rattler/util/node.rb', line 161

def can_equal?(other) #:nodoc:

  self.class == other.class
end

#child(index = 0) ⇒ Object

Return the node’s child at index, or the first/only child if no index is given.



57
58
59
# File 'lib/rattler/util/node.rb', line 57

def child(index = 0)
  children[index]
end

#childrenArray

Return an array of the node’s children



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rattler/util/node.rb', line 39

def children
  @children ||= if @__children__
    if @__children__.size == 1 && @__children__.first.respond_to?(:to_ary)
      @__children__.first
    else
      @__children__
    end
  else
    []
  end
end

#each {|child| ... } ⇒ Object

Call block once for each child, passing that child as an argument.

Yields:



79
80
81
# File 'lib/rattler/util/node.rb', line 79

def each # :yield: child

  block_given? ? children.each { |_| yield _ } : children.each
end

#empty?Boolean

Return true if the node has no children.



109
110
111
# File 'lib/rattler/util/node.rb', line 109

def empty?
  children.empty?
end

#eql?(other) ⇒ Boolean

Return true if the node has the same value as other, i.e. other is an instance of the same class and has equal children and attributes.



145
146
147
148
# File 'lib/rattler/util/node.rb', line 145

def eql?(other)
  self.class == other.class and
  self.same_contents?(other)
end

#inspectObject



172
173
174
175
176
177
# File 'lib/rattler/util/node.rb', line 172

def inspect #:nodoc:

  "#{self.class}[" +
  (children.map {|_| _.inspect } +
    attrs.map {|k, v| k.inspect + '=>' + v.inspect}).join(',') +
  ']'
end

#nameObject

Return the node’s name, which is the node’s name attribute if it has one, otherwise the name of the node’s class.



72
73
74
# File 'lib/rattler/util/node.rb', line 72

def name
  attrs.fetch(:name, self.class.name)
end

#pretty_print(q) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/rattler/util/node.rb', line 180

def pretty_print(q) #:nodoc:

  pretty_print_name(q)
  q.group(1, '[', ']') do
    q.breakable('')
    q.seplist(children) {|_| q.pp _ }
    q.comma_breakable unless children.empty? or pretty_keys.empty?
    q.seplist(pretty_keys) do |k|
      q.pp k
      q.text '=>'
      q.pp attrs[k]
    end
  end
end

#pretty_print_cycle(q) ⇒ Object



195
196
197
# File 'lib/rattler/util/node.rb', line 195

def pretty_print_cycle(q) #:nodoc:

  pretty_print_name(q)
end

#respond_to?(symbol) ⇒ Boolean



156
157
158
# File 'lib/rattler/util/node.rb', line 156

def respond_to?(symbol) #:nodoc:

  super || @attrs.has_key?(symbol)
end

#same_contents?(other) ⇒ Boolean



166
167
168
169
# File 'lib/rattler/util/node.rb', line 166

def same_contents?(other) #:nodoc:

  self.children == other.children and
  self.attrs == other.attrs
end

#to_graphvizObject



200
201
202
# File 'lib/rattler/util/node.rb', line 200

def to_graphviz
  Rattler::Util::GraphViz.digraph(self)
end

#with_attrs(new_attrs) ⇒ Node



95
96
97
# File 'lib/rattler/util/node.rb', line 95

def with_attrs(new_attrs)
  self.with_attrs!(attrs.merge new_attrs)
end

#with_attrs!(new_attrs) ⇒ Node



102
103
104
# File 'lib/rattler/util/node.rb', line 102

def with_attrs!(new_attrs)
  self.class.new(children, new_attrs)
end

#with_children(new_children) ⇒ Node Also known as: with_child



86
87
88
# File 'lib/rattler/util/node.rb', line 86

def with_children(new_children)
  self.class.new(new_children, attrs)
end