Class: Walrus::Grammar::DefDirective

Inherits:
Directive
  • Object
show all
Defined in:
lib/walrus/grammar/def_directive.rb

Direct Known Subclasses

BlockDirective

Instance Method Summary collapse

Instance Method Details

#compile(options = {}) ⇒ Object

Returns a string containing the compiled (Ruby) version of receiver.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/walrus/grammar/def_directive.rb', line 29

def compile options = {}
  internal = ''

  if @params == []
    external = "def #{@identifier.to_s}\n"
  else
    # this will work for the simple case where params are plain identifiers
    params = (@params.kind_of? Array) ? @params : [@params]
    param_list  = params.map { |param| param.compile }.join(', ')
    external = "def #{@identifier.to_s}(#{param_list})\n"
  end

  nested  = nil

  if @content.respond_to? :each
    content = @content
  else
    content = [@content]
  end

  content.each do |element|
    if element.kind_of? Walrus::Grammar::DefDirective
      # must handle nested def blocks here
      inner, outer = element.compile(options)
      nested = ['', ''] if nested.nil?
      external << inner if inner
      nested[1] << "\n" + outer
    else
      # again, may wish to forget the per-line indenting here if it
      # breaks sensitive directive types
      # (#ruby blocks for example, which might have here documents)
      element.compile(options).each do |lines|
        # may return a single line or an array of lines
        lines.each { |line| external << '  ' + line }
      end
    end
  end

  external << "end\n\n"

  if nested
    external << nested[1]
  end

  # better to return nil than an empty string here (which would get
  # indented needlessly)
  internal = nil if internal == ''
  [internal, external]
end