Class: IndentedIO::IndentedIO

Inherits:
Object
  • Object
show all
Includes:
IndentedIOInterface
Defined in:
lib/indented_io/indented_io.rb

Overview

An IO device that writes indented text by reimplementing #write, #print, #printf, #puts, and #p

IndentedIO objects forms a chain that acts as a stack. The lowest element in the stack is always a “pure” IO object (eg. $stdout). IndentedIO object are than moved on and off the stack as indentation levels rise or fall

Note that #new is private. The only way to create a IndentedIO object is to call #indent on an object that supports it (Kernel, IO, or StringIO)

Instance Attribute Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object (private)

Make IndentedIO behave like the underlying @device



80
81
82
# File 'lib/indented_io/indented_io.rb', line 80

def method_missing(method, *args)
  device.send(method, *args)
end

Instance Attribute Details

#depthObject (readonly)

Depth of this object. #depth is always bigger than zero for IndentedIO objects



86
87
88
# File 'lib/indented_io/indented_io.rb', line 86

def depth
  @depth
end

#tabObject (readonly)

Tabulator position for this object. The is the same as the combined length of the indentation levels



90
91
92
# File 'lib/indented_io/indented_io.rb', line 90

def tab
  @tab
end

Instance Method Details

#indent(depth = 1, string_ = self.this_indent, string: string_, bol: nil, &block) ⇒ Object

Returns a IndentedIO object that can be used for printing. The IO object will pass-through all methods to the underlying device except #print, #printf, #puts, and #p

level is the number of leves to indent and string is the string used for indentation. The indentation string can also be given as the keyword parameter :string. Default is the indent string of the outer level or IndentedIO.default_indent if this is the first level. :bol control the beginning-of-line status: If true, #indent will begin writing with an indentation string as if it was at the beginning of the line. If false, it will only indent after the next newline. Default is true

If level is negative, #indent will outdent text instead



20
21
22
# File 'lib/indented_io/indented_io.rb', line 20

def indent(depth=1, string_ = self.this_indent, string: string_, bol: nil, &block)
  interface_indent(depth, string, bol: bol, &block)
end

#p(*args) ⇒ Object

Indent and print args to the underlying device. #p has the same semantic as Kernel#p. Please note that even though #p is only defined on Kernel but can be used on any IndentedIO object so you can say ‘$stderr.p value’



59
60
61
62
63
64
65
66
67
68
# File 'lib/indented_io/indented_io.rb', line 59

def p(*args)
  if bol
    args.each { |arg| write(arg.inspect, "\n") }
  else
    @device.write(args.first.inspect, "\n")
    bol = true
    args[1..-1].each { |arg| write(arg.inspect, "\n") }
  end
  args.size == 1 ? args.first : args
end

Indent and print args to the underlying device. #print has the same semantic as Kernel#print



36
37
38
39
40
41
# File 'lib/indented_io/indented_io.rb', line 36

def print(*args)
  return nil if args.empty?
  write(args.join($, || ''))
  write($\) if $\
  nil
end

#printf(format, *args) ⇒ Object

Indent and print args to the underlying device. #printf has the same semantic as Kernel#printf



45
46
47
# File 'lib/indented_io/indented_io.rb', line 45

def printf(format, *args)
  write format % args
end

#puts(*args) ⇒ Object

Indent and print args to the underlying device. #puts has the same semantic as Kernel#puts



51
52
53
54
# File 'lib/indented_io/indented_io.rb', line 51

def puts(*args)
  write args.join("\n"), "\n"
  nil
end

#write(*args) ⇒ Object

Indent and print args to the underlying device. #write has the same semantic as IO#write



26
27
28
29
30
31
32
# File 'lib/indented_io/indented_io.rb', line 26

def write(*args)
  str = args.join
  return if str.empty?
  s = (bol && str[0] != "\n" ? @combined_indent : "") + str.gsub(/\n([^\n])/m, "\n#{@combined_indent}\\1")
  self.bol = (s[-1] == "\n")
  @device.write(s)
end