Class: Sexp

Inherits:
Object
  • Object
show all
Defined in:
lib/doppelganger/exts/sexp.rb

Overview

This is pulled in part from Ryan Davis’ Sexp additions in Flay.

Instance Method Summary collapse

Instance Method Details

#any_sexp?Boolean

Iterates through each child Sexp of the current Sexp and looks for any Sexp that returns true for the block.

Returns:

  • (Boolean)


71
72
73
74
75
76
# File 'lib/doppelganger/exts/sexp.rb', line 71

def any_sexp?
  self.any? do |sexp|
    next unless Sexp === sexp
    yield sexp
  end
end

#contains_block?(block_node) ⇒ Boolean

Determines if the passed in block node is contained with in the Sexp node.

Returns:

  • (Boolean)


79
80
81
82
83
# File 'lib/doppelganger/exts/sexp.rb', line 79

def contains_block?(block_node)
  self.deep_any? do |sexp|
    sexp == block_node
  end
end

#deep_any?(&block) ⇒ Boolean

Performs the block on every Sexp in this sexp, looking for one that returns true.

Returns:

  • (Boolean)


63
64
65
66
67
# File 'lib/doppelganger/exts/sexp.rb', line 63

def deep_any?(&block)
  self.any_sexp? do |sexp|
    block[sexp] || sexp.deep_any?(&block)
  end
end

#deep_each(&block) ⇒ Object

Performs the block on every Sexp in this sexp.



5
6
7
8
9
10
# File 'lib/doppelganger/exts/sexp.rb', line 5

def deep_each(&block)
  self.each_sexp do |sexp|
    block[sexp]
    sexp.deep_each(&block)
  end
end

#deep_reject(&block) ⇒ Object

Rejects all objects in the Sexp that return true for the block.



37
38
39
40
41
42
43
44
# File 'lib/doppelganger/exts/sexp.rb', line 37

def deep_reject(&block)
  output_sexp = self.reject do |node|
    block[node]
  end
  output_sexp.map_sexps do |sexp|
    sexp.deep_reject(&block)
  end
end

#each_sexpObject

Iterates through each child Sexp of the current Sexp.



55
56
57
58
59
60
# File 'lib/doppelganger/exts/sexp.rb', line 55

def each_sexp
  self.each do |sexp|
    next unless Sexp === sexp
    yield sexp
  end
end

#last_line_numberObject

Finds the last line of the Sexp if that information is available.



13
14
15
16
17
18
19
20
21
# File 'lib/doppelganger/exts/sexp.rb', line 13

def last_line_number
  line_number = nil
  self.deep_each do |sub_node|
    if sub_node.respond_to? :line
      line_number = sub_node.line
    end
  end
  line_number
end

#map_sexpsObject

Maps all sub Sexps into a new Sexp, if the node isn’t a Sexp performs the block and maps the result into the new Sexp.



25
26
27
28
29
30
31
32
33
34
# File 'lib/doppelganger/exts/sexp.rb', line 25

def map_sexps
  self.inject(s()) do |sexps, sexp|
    unless Sexp === sexp
      sexps << sexp
    else
      sexps << yield(sexp)
    end
    sexps
  end
end

#remove_literalsObject

Removes all literals from the Sexp (Symbols aren’t excluded as they are used internally by Sexp for node names which identifies structure important for comparison.)



48
49
50
51
52
# File 'lib/doppelganger/exts/sexp.rb', line 48

def remove_literals
  self.deep_reject do |node|
    !((node.is_a?(Symbol)) || (node.is_a?(Sexp)))
  end
end

#to_flat_aryObject

First turns the Sexp into an Array then flattens it.



86
87
88
# File 'lib/doppelganger/exts/sexp.rb', line 86

def to_flat_ary
  self.to_a.flatten
end