Class: Rattler::Compiler::RubyGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/rattler/compiler/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.

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



31
32
33
34
# File 'lib/rattler/compiler/ruby_generator.rb', line 31

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



19
20
21
22
23
# File 'lib/rattler/compiler/ruby_generator.rb', line 19

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)


41
42
43
44
# File 'lib/rattler/compiler/ruby_generator.rb', line 41

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)


102
103
104
105
106
# File 'lib/rattler/compiler/ruby_generator.rb', line 102

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

#codeString

Return the generated code.

Returns:

  • (String)

    the generated code



151
152
153
# File 'lib/rattler/compiler/ruby_generator.rb', line 151

def code
  @io.string
end

#indentself

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

Returns:

  • (self)


66
67
68
69
70
71
72
# File 'lib/rattler/compiler/ruby_generator.rb', line 66

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)


124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/rattler/compiler/ruby_generator.rb', line 124

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)


144
145
146
# File 'lib/rattler/compiler/ruby_generator.rb', line 144

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)


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

def newline
  @io.puts
  start_line
end

#start_lineself

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

Returns:

  • (self)


49
50
51
52
# File 'lib/rattler/compiler/ruby_generator.rb', line 49

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

#suffix(s) ⇒ self

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

Returns:

  • (self)


77
78
79
80
# File 'lib/rattler/compiler/ruby_generator.rb', line 77

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)


89
90
91
92
# File 'lib/rattler/compiler/ruby_generator.rb', line 89

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