indented_io 0.7.3 → 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
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