Class: Rattler::BackEnd::RubyGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/rattler/back_end/ruby_generator.rb

Overview

A RubyGenerator is used to generate well-formatted ruby code. It keeps track of the indent level and has various methods for adding code, all of which return self to allow method chaining.

Author:

  • Jason Arhart

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ RubyGenerator

Create a new RubyGenerator with the given options.

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :indent_level (Integer) — default: 0

    the initial indent level

  • :io (StringIO) — default: StringIO.new

    the StringIO object that the generator will write the generated code to



40
41
42
43
# File 'lib/rattler/back_end/ruby_generator.rb', line 40

def initialize(options = {})
  @indent_level = options[:indent_level] || 0
  @io = options[:io] || StringIO.new
end

Class Method Details

.code(options = {}) {|RubyGenerator| ... } ⇒ String

Create a new RubyGenerator with the given options, yield it to the block, and return the code generated by the block.

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :indent_level (Integer) — default: 0

    the initial indent level

  • :io (StringIO) — default: StringIO.new

    the StringIO object that the generator will write the generated code to

Yields:

Returns:

  • (String)

    the code generated by the block



28
29
30
31
32
# File 'lib/rattler/back_end/ruby_generator.rb', line 28

def self.code(options = {})
  generator = self.new(options)
  yield generator
  generator.code
end

Instance Method Details

#<<(s) ⇒ self

Add arbirtrary code.

Parameters:

  • s (String)

    the code to add

Returns:

  • (self)


50
51
52
53
# File 'lib/rattler/back_end/ruby_generator.rb', line 50

def <<(s)
  @io << s
  self
end

#block(before, after = 'end') ⇒ self

Generate a multiline indented block with the code generated in the given block, opening the block with before and closing it with after.

Parameters:

  • before (String)

    the code to open the block

  • after (String) (defaults to: 'end')

    the code to close the block

Returns:

  • (self)


111
112
113
114
115
# File 'lib/rattler/back_end/ruby_generator.rb', line 111

def block(before, after='end')
  self << before
  indent { yield }
  newline << after
end

#codeString

Return the generated code.

Returns:

  • (String)

    the generated code



160
161
162
# File 'lib/rattler/back_end/ruby_generator.rb', line 160

def code
  @io.string
end

#indentself

Increase the indent level and start a new line for the given block.

Returns:

  • (self)


75
76
77
78
79
80
81
# File 'lib/rattler/back_end/ruby_generator.rb', line 75

def indent
  @indent_level += 1
  newline
  yield
  @indent_level -= 1
  self
end

#intersperse(enum, opts = {}) {|element| ... } ⇒ self

Add a separator or newlines or both in between code generated in the given block for each element in enum. Newlines, are always added after the separator.

Parameters:

  • enum (Enumerable)

    an enumerable sequence of objects

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :sep (String) — default: nil

    optional separator to use between elements

  • :newline (true, false) — default: false

    separate with a single newline if true (and if :newlines is not specified)

  • :newlines (Integer) — default: nil

    optional number of newlines to use between elements (overrides :newline)

Yields:

  • (element)

    each element in enum

Returns:

  • (self)


133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/rattler/back_end/ruby_generator.rb', line 133

def intersperse(enum, opts={})
  sep = opts[:sep]
  newlines = opts[:newlines] || (opts[:newline] ? 1 : 0)
  enum.each_with_index do |_, i|
    if i > 0
      self << sep if sep
      newlines.times { newline }
    end
    yield _
  end
  self
end

#intersperse_nl(enum, sep) {|element| ... } ⇒ self

Add sep followed by a newline in between code generated in the given block for each element in enum.

Parameters:

  • enum (Enumerable)

    an enumerable sequence of objects

Yields:

  • (element)

    each element in enum

Returns:

  • (self)


153
154
155
# File 'lib/rattler/back_end/ruby_generator.rb', line 153

def intersperse_nl(enum, sep)
  intersperse(enum, :sep => sep, :newline => true) {|_| yield _ }
end

#newlineself

Add a line break followed by the appropriate amount of space to indent the start of a line.

Returns:

  • (self)


67
68
69
70
# File 'lib/rattler/back_end/ruby_generator.rb', line 67

def newline
  @io.puts
  start_line
end

#start_lineself

Add the appropriate amount of space to indent the start of a line.

Returns:

  • (self)


58
59
60
61
# File 'lib/rattler/back_end/ruby_generator.rb', line 58

def start_line
  @io << ('  ' * @indent_level)
  self
end

#suffix(s) ⇒ self

Append the given string after code generated in the given block.

Returns:

  • (self)


86
87
88
89
# File 'lib/rattler/back_end/ruby_generator.rb', line 86

def suffix(s)
  yield
  self << s
end

#surround(before, after) ⇒ self

Append before, followed by the code generated in the given block, followed by after.

Parameters:

  • before (String)

    the code to append before the block

  • after (String)

    the code to append after the block

Returns:

  • (self)


98
99
100
101
# File 'lib/rattler/back_end/ruby_generator.rb', line 98

def surround(before, after)
  self << before
  suffix(after) { yield }
end