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

Overloads:

  • .Node.[]Node

    Returns a Node object with no children or attributes.

    Returns:

    • (Node)

      a Node object with no children or attributes

  • .Node.[](child...) ⇒ Node

    Returns a Node object with children and no attributes.

    Returns:

    • (Node)

      a Node object with children and no attributes

  • .Node.[](attribute...) ⇒ Node

    Returns a Node object with attributes and no children.

    Returns:

    • (Node)

      a Node object with attributes and no children

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

    Returns a Node object with children and attributes.

    Returns:

    • (Node)

      a Node object with children and attributes



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.

Returns:

  • (Boolean)

    true if the node is equal to other



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.

Overloads:

  • #[](index) ⇒ Object

    Returns the child at index.

    Parameters:

    • index (Integer)

      index of the child

    Returns:

    • the child at index

  • #[](start, length) ⇒ Array

    Returns the node’s children starting at start and continuing for length children.

    Parameters:

    • start (Integer)

      the index of the first child

    • length (Integer)

      the number of children to return

    Returns:

    • (Array)

      the node’s children starting at start and continuing for length children

  • #[](range) ⇒ Array

    Returns the node’s children specified by range.

    Parameters:

    • range (Range)

      the range of children

    Returns:

    • (Array)

      the node’s children specified by range



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

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

#attrsHash

Return a the node’s attributes.

Returns:

  • (Hash)

    the node’s attributes



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

def attrs
  @attrs ||= {}
end

#can_equal?(other) ⇒ Boolean

Returns:

  • (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.

Parameters:

  • index (Integer) (defaults to: 0)

Returns:

  • the 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

Returns:

  • (Array)

    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.

Returns:

  • (Boolean)

    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.

Returns:

  • (Boolean)

    true the node has the same value as other



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.

Returns:

  • the node’s name



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

Returns:

  • (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

Returns:

  • (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

Returns a new GraphViz digraph object representing the node.

Returns:

  • a new GraphViz digraph object representing the node



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

Returns a new node with the new attributes added to the node’s attributes.

Returns:

  • (Node)

    a new node with the new attributes added to the node’s attributes



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

Returns a new node with the new attributes replacing the node’s attributes.

Parameters:

  • new_attrs (Hash)

    a new set of attributes

Returns:

  • (Node)

    a new node with the new attributes replacing the node’s attributes



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

Returns a new code with the new children replacing the node’s children.

Parameters:

  • new_children (Array)

    a new array of children

Returns:

  • (Node)

    a new code with the new children replacing the node’s children



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

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