indented_io 0.7.3 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f678cdfa6edee19dad6a5256367071ceea8d1ca7ebb5dd4556330f260250e0e1
4
- data.tar.gz: a2cb615747e62ca14ed25b872ae501c9f6b0dbaadd1a9ec73f3a2dbfcd519f61
3
+ metadata.gz: 2065a8b32b45c15d23fca5af4899cde35fefae5e1df980bfcf90423aa0884cc2
4
+ data.tar.gz: 83aad862d7eefe03af50b833f94579bcb67dd9a049d7827ac354949055d9fb9d
5
5
  SHA512:
6
- metadata.gz: 914ca7aef4d7017fc4899c2f1cc19da8a7cf6bacc7c0937bd28033bef7cb2350f3878bd0ac9380301d4e2b0cb7df6aded579085a7a52c0f48206e80dbe6b3a7a
7
- data.tar.gz: 5dcf284b39596f7faaff975d2e703125caa157c133646a1aa9a2147bb95b7c4c852de61c3bcdc872208c08d79a7d4acc42a0170d168d66e9a56199082ed5d328
6
+ metadata.gz: 4a3e1eef0a3a6d2807504c4d000a39d08093bb44381ed6eac0c1d1ae5c7dccf5e60a0c00fd07316c19329e5e1f49fb3b4662adbfb0df82a55c0206f2d6915f4e
7
+ data.tar.gz: ba4d79601f35265184d85629a57773b34cca6b7913220c629d332b2762762dc946337f21b4ce9c4b896866ef8efa99b4a9d5748f27ce93a71c31a5d9a2c0e4ed
data/README.md CHANGED
@@ -11,9 +11,9 @@ adds to the previous indendation
11
11
  ```ruby
12
12
  require 'indented_io'
13
13
 
14
- puts "Not indented"
15
- indent { puts "Indented one level" }
16
- indent(2, "* ").puts "Indented two levels"
14
+ puts 'Not indented'
15
+ indent { puts 'Indented one level' }
16
+ indent(2, '* ').puts 'Indented two levels'
17
17
  ```
18
18
 
19
19
  outputs
@@ -32,9 +32,9 @@ If given a block, the block will be called with the IndentedIO object as
32
32
  argument:
33
33
 
34
34
  ```ruby
35
- $stdout.puts "Not indented"
36
- $stdout.indent.puts "Indented"
37
- $stdout.indent { |f| f.puts "Indented" }
35
+ $stdout.puts 'Not indented'
36
+ $stdout.indent.puts 'Indented'
37
+ $stdout.indent { |f| f.puts 'Indented' }
38
38
 
39
39
  # Not indented
40
40
  # Indented
@@ -51,10 +51,10 @@ symbolic argument `:string`. If level is negative, the text will be outdented
51
51
  instead:
52
52
 
53
53
  ```ruby
54
- $stdout.puts "Not indented"
55
- $stdout.indent(2, "> ") do |f|
56
- f.indent(string: "* ").puts "Indented three levels"
57
- f.indent(-1).puts "Indented one level"
54
+ $stdout.puts 'Not indented'
55
+ $stdout.indent(2, '> ') do |f|
56
+ f.indent(string: '* ').puts 'Indented three levels'
57
+ f.indent(-1).puts 'Indented one level'
58
58
  end
59
59
 
60
60
  # Not indented
@@ -71,15 +71,15 @@ that `Kernel#print`, `Kernel#printf`, `Kernel#puts`, and `Kernel#p` will output
71
71
  indented within that block:
72
72
 
73
73
  ```ruby
74
- puts "Not indented"
74
+ puts 'Not indented'
75
75
  indent do
76
- puts "Indented one level"
76
+ puts 'Indented one level'
77
77
  indent do
78
- puts "Indented two levels"
78
+ puts 'Indented two levels'
79
79
  end
80
- puts "Indented one level"
80
+ puts 'Indented one level'
81
81
  end
82
- puts "Not indented"
82
+ puts 'Not indented'
83
83
 
84
84
  # Not indented
85
85
  # Indented one level
@@ -95,8 +95,8 @@ def legacy(phrase)
95
95
  puts phrase
96
96
  end
97
97
 
98
- legacy("Not indented")
99
- indent { legacy("Indented" }
98
+ legacy('Not indented')
99
+ indent { legacy('Indented' }
100
100
 
101
101
  # Not indented
102
102
  # Indented
@@ -111,8 +111,8 @@ that specify if the output device is at the beginning of a line and that printin
111
111
  should start with an indentation string:
112
112
 
113
113
  ```ruby
114
- indent(1, bol: true).puts "Indented"
115
- indent(1, bol: false).puts "Not indented\nIndented"
114
+ indent(1, bol: true).puts 'Indented'
115
+ indent(1, bol: false).puts 'Not indented\nIndented'
116
116
 
117
117
  # Indented
118
118
  # Not indented
@@ -124,7 +124,7 @@ indent(1, bol: false).puts "Not indented\nIndented"
124
124
  The default indentation string is defined in `IndentedIO`:
125
125
 
126
126
  ```ruby
127
- IndentedIO.default_indent = ">> "
127
+ IndentedIO.default_indent = '>> '
128
128
  indent.puts "Indented by #{IndentedIO.default_indent.inspect}"
129
129
 
130
130
  # >> Indented by ">> "
@@ -142,19 +142,19 @@ In case of errors an `IndentedIO::Error` exception is raised
142
142
 
143
143
  You can add support for your own IO objects by including
144
144
  `IndentedIO::IndentedIOInterface` in your class. All that is required is that
145
- the class define a `#print` method with the same semantics as the system
146
- `#print`
145
+ the class define a `#write` method with the same semantics as `IO#write`
146
+ (convert arguments to strings and then write them)
147
147
 
148
148
  ```ruby
149
149
  require 'indented_io'
150
150
  class MyIO
151
151
  include IndentedIO::IndentedIOInterface
152
- def print(*args) ... end
152
+ def write(*args) ... end
153
153
  end
154
154
 
155
155
  my_io = MyIO.new
156
- my_io.puts "Not indented"
157
- my_io.indent.puts "It works!"
156
+ my_io.puts 'Not indented'
157
+ my_io.indent.puts 'It works!'
158
158
 
159
159
  # Not indented
160
160
  # It works!
@@ -168,13 +168,13 @@ with a block without parameters manipulates `$stdout`, replacing it with an
168
168
  `IndentedIO` object for the duration of the block
169
169
 
170
170
  The implementation carries no overhead if it is not used but the core
171
- indentation mechanism processes characters one-by-one which is about 10-15
172
- times slower than a handwritten implementation (scripts/perf.rb is a script to
173
- check performance). It would be much faster if the inner loop was implemented
174
- in C. However, we're talking micro-seconds here: Printing without using
175
- IndentedIO range from around 0.25ms to 1ms while using IndentedIO slows it down
176
- to between 4 and 12 microseconds, so IndentedIO won't cause a noticeable slow
177
- down of your application
171
+ indentation mechanism processes characters one-by-one which is about 7-8 times
172
+ slower than a handwritten implementation (scripts/perf.rb is a script to check
173
+ performance). It would be much faster if the inner loop was implemented in C.
174
+ However, we're talking micro-seconds here: Printing without using IndentedIO
175
+ range from around 0.25us to 1us while using IndentedIO slows it down to between
176
+ 2us and 8us, so IndentedIO won't cause a noticeable slow down of your
177
+ application unless you do a lot of output
178
178
 
179
179
  ## Installation
180
180
 
data/TODO CHANGED
@@ -2,14 +2,20 @@
2
2
  TODO
3
3
  o Check if IO object is writable - no good solution ?
4
4
  o better name for @this_indent ? 'string' ?
5
- o Change dependency in IndentedIOInterface from #print to #write and bump
6
- version to 0.8 as this is the last user-visible change to be made
7
5
  o Reimplement core loop in C
8
6
  o Create BaseIndentedIO to hold bol status and remove it from IndentedIO
9
7
  o Transmogrify instances variables and protected methods in IndentedIO to
10
8
  avoid collision with names from the underlying device
11
9
  o Explain name collision issues in the docs
12
10
 
11
+ + Remove IndentedIO#dump
12
+ + Change dependency in IndentedIOInterface from #print to #write and bump
13
+ version to 0.8 as this is the last user-visible change to be made
14
+ + Oops. #print reimplemention doesn't do this:
15
+ If the output field separator ($,) is not nil, it is inserted between
16
+ objects. If the output record separator ($\) is not nil, it is appended to
17
+ the output
18
+ + Tests for #write
13
19
  + explain bol
14
20
  + Allow a symbolic :string argument
15
21
  + #printf !
data/indented_io.gemspec CHANGED
@@ -37,6 +37,6 @@ Gem::Specification.new do |spec|
37
37
  spec.require_paths = ["lib"]
38
38
 
39
39
  spec.add_development_dependency "bundler", "~> 1.16"
40
- spec.add_development_dependency "rake", "~> 10.0"
40
+ spec.add_development_dependency "rake", ">= 12.3.3"
41
41
  spec.add_development_dependency "rspec", "~> 3.0"
42
42
  end
@@ -20,48 +20,48 @@ module IndentedIO
20
20
  interface_indent(levels, string, bol: bol, &block)
21
21
  end
22
22
 
23
+ # Indent and print args to the underlying device. #write has the same semantic
24
+ # as IO#write
25
+ def write(*args)
26
+ str = args.join
27
+ return if str.empty?
28
+ s = (bol && str[0] != "\n" ? @combined_indent : "") + str.gsub(/\n([^\n])/m, "\n#{@combined_indent}\\1")
29
+ self.bol = (s[-1] == "\n")
30
+ @device.write(s)
31
+ end
32
+
23
33
  # Indent and print args to the underlying device. #print has the same semantic
24
34
  # as Kernel#print
25
35
  def print(*args)
26
- if bol
27
- @device.print @combined_indent
28
- self.bol = false
29
- end
30
- args.join.each_char { |c|
31
- if c == "\n"
32
- self.bol = true
33
- elsif bol
34
- @device.print @combined_indent
35
- self.bol = false
36
- end
37
- @device.print c
38
- }
36
+ return nil if args.empty?
37
+ write(args.join($, || ''))
38
+ write($\) if $\
39
39
  nil
40
40
  end
41
41
 
42
42
  # Indent and print args to the underlying device. #printf has the same semantic
43
43
  # as Kernel#printf
44
44
  def printf(format, *args)
45
- print format % args
45
+ write format % args
46
46
  end
47
47
 
48
48
  # Indent and print args to the underlying device. #puts has the same semantic
49
49
  # as Kernel#puts
50
50
  def puts(*args)
51
- args.each { |arg| print(arg, "\n") }
51
+ write args.join("\n"), "\n"
52
52
  nil
53
53
  end
54
54
 
55
55
  # Indent and print args to the underlying device. #p has the same semantic
56
- # as Kernel#p. Please note that #p is usually not defined on other classes
57
- # then Kernel but can be used on any IndentedIO object
56
+ # as Kernel#p. Please note that #p is only defined on Kernel in the Ruby core
57
+ # library but can be used on any IndentedIO object
58
58
  def p(*args)
59
59
  if bol
60
- args.each { |arg| print(arg.inspect, "\n") }
60
+ args.each { |arg| write(arg.inspect, "\n") }
61
61
  else
62
- @device.print args.first.inspect, "\n"
62
+ @device.write(args.first.inspect, "\n")
63
63
  bol = true
64
- args[1..-1].each { |arg| print(arg.inspect, "\n") }
64
+ args[1..-1].each { |arg| write(arg.inspect, "\n") }
65
65
  end
66
66
  args.size == 1 ? args.first : args
67
67
  end
@@ -69,7 +69,7 @@ module IndentedIO
69
69
  # Make IndentedIO behave like the underlying @device
70
70
  # @!visibility private
71
71
  def respond_to?(method)
72
- [:indent, :level, :print, :puts, :p].include?(method) || device.respond_to?(method)
72
+ [:indent, :level, :print, :printf, :puts, :p].include?(method) || device.respond_to?(method)
73
73
  end
74
74
 
75
75
  # Make IndentedIO behave like the underlying @device
@@ -85,8 +85,8 @@ module IndentedIO
85
85
  attr_reader :device
86
86
 
87
87
  # First IndentedIO object on the stack. Equal to self if self is the first
88
- # indentation object. #base is used to keep track of #bol for the whole
89
- # stack of IndentedIO objects
88
+ # indentation object. The #base object is used to keep track of #bol for
89
+ # the whole stack of IndentedIO objects
90
90
  attr_reader :base
91
91
 
92
92
  # Parent IndentedIO or IO object
@@ -146,18 +146,5 @@ module IndentedIO
146
146
  self.bol = (bol.nil? ? true : bol)
147
147
  end
148
148
  end
149
-
150
- public
151
- # @!visibility private
152
- def dump
153
- $stderr.puts "#{self.class} [#{self.object_id}]"
154
- $stderr.puts " device: #{device.class} [#{device.object_id}]"
155
- $stderr.puts " base : #{base.class} [#{base.object_id}]"
156
- $stderr.puts " parent: #{parent.class} [#{parent.object_id}]"
157
- $stderr.puts " levels: #{levels}"
158
- $stderr.puts " this_indent: #{this_indent.inspect}"
159
- $stderr.puts " combined_indent: #{combined_indent.inspect}"
160
- $stderr.puts " bol: #{bol}"
161
- end
162
149
  end
163
150
  end
@@ -1,12 +1,13 @@
1
1
  module IndentedIO
2
2
  # IndentedIO interface that provides the #indent method. It is used by IO,
3
3
  # StringIO, and IndentedIO but can be included in any class that define a
4
- # #print method like this:
4
+ # #write method like this:
5
5
  #
6
6
  # require 'indented_io'
7
+ #
7
8
  # class MyIO
8
9
  # include IndentedIO::IndentedIOInterface
9
- # def print(*args) ... end
10
+ # def write(*args) ... end
10
11
  # end
11
12
  #
12
13
  # my_io = MyIO.new
@@ -18,7 +19,7 @@ module IndentedIO
18
19
  #
19
20
  module IndentedIOInterface
20
21
  # Returns a IndentedIO object that can be used for printing. The IO object
21
- # will pass-through all method to the underlying device except #print,
22
+ # will pass-through all methods to the underlying device except #print,
22
23
  # #printf, #puts, and #p
23
24
  #
24
25
  # +level+ is the number of leves to indent and +string+ is the string used
@@ -3,7 +3,7 @@ require 'indented_io/indented_io_interface'
3
3
  module Kernel
4
4
  # Like {IndentedIO::IndentedIOInterface#indent} except the underlying device is
5
5
  # not the receiver (Kernel) but $stdout. Kernel#indent also allows a block without
6
- # and argument. In that case it manipulates $stdout to print indented:
6
+ # an argument. In that case it manipulates $stdout to print indented:
7
7
  #
8
8
  # puts "Not indented
9
9
  # indent do
@@ -1,3 +1,4 @@
1
+ require 'stringio' # Requiered to avoid 'superclass mismatch' errors in other modules
1
2
  require 'indented_io/indented_io_interface'
2
3
 
3
4
  # Includes the IndentedIOInterface that define the #indent method
@@ -1,4 +1,4 @@
1
1
  module IndentedIO
2
2
  # Version number
3
- VERSION = "0.7.3"
3
+ VERSION = '0.8.4'
4
4
  end
data/scripts/perf.rb CHANGED
@@ -7,15 +7,24 @@ RUNS = 1_000_000
7
7
  saved_stdout = $stdout
8
8
  $stdout = File.open("/dev/null", "w")
9
9
 
10
- def timeit(&block)
10
+ $base = 0.0
11
+
12
+ def timeit_impl(&block)
11
13
  t0 = Time.now
12
14
  RUNS.times {
13
15
  yield
14
16
  }
15
17
  t1 = Time.now
16
- (1000 * (t1 - t0)).round(0)
18
+ t1 - t0 - $base
17
19
  end
18
20
 
21
+ $base = timeit_impl {}
22
+
23
+ def timeit(&block)
24
+ (1000 * timeit_impl(&block)).round(0)
25
+ end
26
+
27
+
19
28
  def report(title, wo_indent, w_indent)
20
29
  times = (w_indent / wo_indent).round(1)
21
30
  if times < 1.1
@@ -56,7 +65,7 @@ dynamic_wo_indent = timeit {
56
65
  }
57
66
 
58
67
  dynamic_w_indent = nil
59
- indent(" ") {
68
+ indent(:string => " ") {
60
69
  dynamic_w_indent = timeit { puts "Indented" }
61
70
  }
62
71
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: indented_io
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.3
4
+ version: 0.8.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claus Rasmussen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-13 00:00:00.000000000 Z
11
+ date: 2021-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 12.3.3
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: 12.3.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -104,8 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
104
  - !ruby/object:Gem::Version
105
105
  version: '0'
106
106
  requirements: []
107
- rubyforge_project:
108
- rubygems_version: 2.7.3
107
+ rubygems_version: 3.0.8
109
108
  signing_key:
110
109
  specification_version: 4
111
110
  summary: Print indented text