report_print 0.1.2 → 0.2.0

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: 95d2ad3bb32255b708ff4f8b2e8f60e300cd40a1d7bab2e352ca1b355ddf8bad
4
- data.tar.gz: 13740735a26e08b56e1f0d2e790524afd3ec73789465a65117f2f62555177220
3
+ metadata.gz: d6bc69172badef1f367d722882bf9dfc8dcaffb66926811cc37ddebcffac68a8
4
+ data.tar.gz: 1fdb2ce8ed7441c34f6cc792480fc9b7ad614c0d26204cf237ada5c52f9969bc
5
5
  SHA512:
6
- metadata.gz: 87218676c7e05ef0ec0f7243dc2558da038c4abac79f21a9eee2df00e730545e5add08761195d40238303241b9181198bab19da7acef422e57656d00f5b86db3
7
- data.tar.gz: 5b17164200cdbc4fbb24a39e5206368766bead5277126c81753be4d9cfdcdf52df202d857eda1e15bc28b39bae95cd7641c015e0fc8eae6301fc48e18eef6884
6
+ metadata.gz: b701bc0e9ac1896140001a39967d96ea4acc369fc7ae8a619a0e62035aa16ace37dcebcb6757abb5f0d3deb93be1e1f8381b31cc90c1e7aadd4a687cbcec0bec
7
+ data.tar.gz: 74c6fb521894a4f14591d5d0e23f1b941c04b5209fe9dfb880b35f84041a27c6f917aee484e6402ec555e466fd5a6e3fb582ba60c3ad1432b452f1385c7b4baa
data/README.md CHANGED
@@ -23,7 +23,29 @@ gem install report_print
23
23
  ```ruby
24
24
  require 'report_print'
25
25
 
26
- rp object
26
+ class Example
27
+ def initialize
28
+ @foo = { a: [1,2,3] }
29
+ @bar = Object.new
30
+ end
31
+ end
32
+
33
+ rp Example.new
34
+ ```
35
+
36
+ Output:
37
+
38
+ ```text
39
+ Example 0x378
40
+ @foo = {
41
+ a: [
42
+ 1,
43
+ 2,
44
+ 3
45
+ ]
46
+ }
47
+ @bar = Object 0x3a8
48
+ end
27
49
  ```
28
50
 
29
51
  See the [full documentation](https://benoithiller.github.io/report_print/) for more details.
data/doc/Formatters.md CHANGED
@@ -10,6 +10,7 @@ A number of simple value types are configured to produce colorized versions of t
10
10
 
11
11
  rp :symbols
12
12
  rp "strings"
13
+ rp /regex/
13
14
 
14
15
  # All Numeric types
15
16
  rp 1
@@ -27,7 +28,8 @@ Output:
27
28
 
28
29
  <pre>
29
30
  <span style="color:var(--code-blue)">:symbols<span style="color:var(--code-green)">
30
- "strings"<span style="color:var(--code-purple)">
31
+ "strings"<span style="color:var(--code-orange)">
32
+ /regex/<span style="color:var(--code-purple)">
31
33
  1
32
34
  0.5
33
35
  Infinity
@@ -165,3 +167,19 @@ Output:
165
167
  </pre>
166
168
 
167
169
  Note that the object id is included for `Struct` but not for `Data` as the latter is a flyweight while the former is essentially an ordinary class.
170
+
171
+ ## `Range` and `ArithmeticSequence`
172
+
173
+ rp(1..10)
174
+ rp(..10)
175
+ rp((1...10).step(2))
176
+ rp("a".."z")
177
+
178
+ Output:
179
+
180
+ <pre>
181
+ (<span style="color:var(--code-purple)">1</span>..<span style="color:var(--code-purple)">10</span>)
182
+ (..<span style="color:var(--code-purple)">10</span>)
183
+ (<span style="color:var(--code-purple)">1</span>...<span style="color:var(--code-purple)">10</span>).step(<span style="color:var(--code-purple)">2</span>)
184
+ (<span style="color:var(--code-green)">"a"</span>..<span style="color:var(--code-green)">"z"</span>)</span>
185
+ </pre>
data/gem_description.rdoc CHANGED
@@ -2,8 +2,4 @@ A hybrid between PrettyPrint and AwesomePrint/AmazingPrint. Providing you both a
2
2
 
3
3
  The name ReportPrint comes from the desire to output detailed reports of the program state at a given point in time, rather than merely inspecting an object.
4
4
 
5
- == Usage
6
-
7
- require 'report_print'
8
-
9
- rp object
5
+ After requiring simply use the global `rp` method to print objects like you do with `pp` or `ap`.
data/lib/.document CHANGED
@@ -1,2 +1,3 @@
1
1
  report_print/printer.rb
2
2
  report_print/dsl.rb
3
+ report_print/api.rb
@@ -0,0 +1,61 @@
1
+ module ReportPrint
2
+ ##
3
+ # These are the extensions that are included into the Module class that
4
+ # enabled you to customize the behaviour of ReportPrint for your own classes.
5
+ module Api
6
+ ##
7
+ # Defines options used by the printer when printing instances of the
8
+ # current class.
9
+ #
10
+ # The currently supported options are:
11
+ #
12
+ # * `detect_cycles:` whether instances of this class should display just a
13
+ # header and id when printed multiple times by the same report print
14
+ # command.
15
+ # <br>
16
+ # Defaults to `true` except for in the case of the simple value types and
17
+ # Data classes.
18
+ # * `color:` the color value to apply when using #report_print_inspect!.
19
+ # <br>
20
+ # Defaults to `nil`.
21
+ #
22
+ # #### Example Usage
23
+ #
24
+ # ```
25
+ # class WithColor
26
+ # report_print_options(color: :bright_blue)
27
+ # report_print_inspect!
28
+ # end
29
+ #
30
+ # class CustomContainer
31
+ # report_print_options(detect_cycles: false)
32
+ # end
33
+ # ```
34
+ #
35
+ # #### Option Loading
36
+ #
37
+ # Setting any value to `nil` means: take the global value if it is defined.
38
+ #
39
+ # When ReportPrint fetches options for a given class it first fetches the
40
+ # superclass options (recursively), then it merges the options for the
41
+ # current class on top.
42
+ #
43
+ # After which it compacts the options (removing the nils) and merges them
44
+ # on top of any global options. Where the global options are currently
45
+ # specified by calling `ReportPrint.report_print_options`.
46
+ def report_print_options(**kwargs)
47
+ @report_print_options = (@report_print_options || {}).merge(kwargs)
48
+ end
49
+
50
+ ##
51
+ # Helper that defines a `report_print` method which calls `inspect` and
52
+ # applies the `color:` specified in #report_print_options.
53
+ def report_print_inspect!
54
+ define_method(:report_print) do |rp|
55
+ rp.write(inspect, color: rp.options_for(self)[:color])
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ Module.prepend(ReportPrint::Api)
@@ -1,47 +1,114 @@
1
1
  using ReportPrint::Refinements
2
2
 
3
- class ::Object < ::BasicObject
3
+ class ::Module < ::Object
4
4
  def report_print(rp)
5
- rp.unless_seen(self) do
6
- rp.write_header(self)
7
- rp.multiline(after: rp.color("end", :bright_blue), after_empty: false) do
8
- rp.write_instance_variables(self)
9
- end
10
- end
5
+ rp.write(short_class_name, color: :bright_yellow)
11
6
  end
12
7
  end
13
8
 
14
- class ::Module < ::Object
9
+ class ::Object < ::BasicObject
10
+ report_print_options(detect_cycles: true)
11
+
15
12
  def report_print(rp)
16
- rp.write(short_class_name, color: :bright_yellow)
13
+ rp.write_header(self)
14
+ rp.multiline(after: rp.color("end", :bright_blue), after_empty: false) do
15
+ rp.write_instance_variables(self)
16
+ end
17
+ end
18
+
19
+ def report_print_cycle(rp)
20
+ rp.write_header(self)
17
21
  end
18
22
  end
19
23
 
20
24
  class ::Symbol < ::Object
21
- report_print_inspect!(color: :bright_blue)
25
+ report_print_options(color: :bright_blue, detect_cycles: false)
26
+ report_print_inspect!
22
27
  end
23
28
 
24
29
  class ::TrueClass < ::Object
25
- report_print_inspect!(color: :bright_blue)
30
+ report_print_options(color: :bright_blue, detect_cycles: false)
31
+ report_print_inspect!
26
32
  end
27
33
 
28
34
  class ::FalseClass < ::Object
29
- report_print_inspect!(color: :bright_blue)
35
+ report_print_options(color: :bright_blue, detect_cycles: false)
36
+ report_print_inspect!
30
37
  end
31
38
 
32
39
  class ::Numeric < ::Object
33
- report_print_inspect!(color: :bright_magenta)
40
+ report_print_options(color: :bright_magenta, detect_cycles: false)
41
+ report_print_inspect!
34
42
  end
35
43
 
36
44
  class ::String < ::Object
37
- report_print_inspect!(color: :bright_green)
45
+ report_print_options(color: :bright_green, detect_cycles: false)
46
+ report_print_inspect!
38
47
  end
39
48
 
40
49
  class ::NilClass < ::Object
41
- report_print_inspect!(color: :bright_blue)
50
+ report_print_options(color: :bright_blue, detect_cycles: false)
51
+ report_print_inspect!
52
+ end
53
+
54
+ class ::Regexp < ::Object
55
+ report_print_options(color: :yellow, detect_cycles: false)
56
+ report_print_inspect!
57
+ end
58
+
59
+ class ::Range < ::Object
60
+ report_print_options(detect_cycles: false)
61
+
62
+ def report_print(rp)
63
+ first = self.first rescue nil
64
+ last = self.last rescue nil
65
+
66
+ rp.inline("") do
67
+ rp.write("(")
68
+ unless first.nil?
69
+ rp.rp(first)
70
+ end
71
+ rp.write("..")
72
+ if exclude_end?
73
+ rp.write(".")
74
+ end
75
+ unless last.nil?
76
+ rp.rp(last)
77
+ end
78
+ rp.write(")")
79
+ end
80
+ end
81
+ end
82
+
83
+ class ::Enumerator::ArithmeticSequence ::Enumerator
84
+ report_print_options(detect_cycles: false)
85
+
86
+ def report_print(rp)
87
+ rp.inline("") do
88
+ rp.write("(")
89
+ unless self.begin.nil?
90
+ rp.rp(self.begin)
91
+ end
92
+ rp.write("..")
93
+ if exclude_end?
94
+ rp.write(".")
95
+ end
96
+ unless self.end.nil?
97
+ rp.rp(self.end)
98
+ end
99
+ rp.write(")")
100
+ unless step == 1
101
+ rp.write(".step(")
102
+ rp.rp(step)
103
+ rp.write(")")
104
+ end
105
+ end
106
+ end
42
107
  end
43
108
 
44
109
  class ::Array < ::Object
110
+ report_print_options(detect_cycles: false)
111
+
45
112
  def report_print(rp)
46
113
  rp.write("[")
47
114
  rp.multiline(after: "]", separator: ",") do
@@ -53,6 +120,8 @@ class ::Array < ::Object
53
120
  end
54
121
 
55
122
  class ::Hash < ::Object
123
+ report_print_options(detect_cycles: false)
124
+
56
125
  def report_print(rp)
57
126
  rp.write("{")
58
127
  rp.multiline(after: "}", separator: ",") do
@@ -74,6 +143,8 @@ class ::Hash < ::Object
74
143
  end
75
144
 
76
145
  class ::Set < ::Object
146
+ report_print_options(detect_cycles: false)
147
+
77
148
  def report_print(rp)
78
149
  rp.inline("") do
79
150
  rp.write("Set", color: :yellow)
@@ -88,6 +159,8 @@ class ::Set < ::Object
88
159
  end
89
160
 
90
161
  class ::Data < ::Object
162
+ report_print_options(detect_cycles: false)
163
+
91
164
  def report_print(rp)
92
165
  name = self.class.short_class_name
93
166
  rp.inline("") do
@@ -19,3 +19,5 @@ module ReportPrint
19
19
  end
20
20
  end
21
21
  end
22
+
23
+ Kernel.prepend(ReportPrint::Dsl)
@@ -13,16 +13,12 @@ module ReportPrint
13
13
  :next_inline_separator,
14
14
  :after,
15
15
  :start_of_line,
16
- :start_of_block
16
+ :start_of_block,
17
+ :start_of_output
17
18
  ) do
18
- # Ruby type checking can't really handle this type of dynamic programming
19
- # very well yet, so we just skip type checking here as there is only the
20
- # one short function.
21
- # steep:ignore:start
22
19
  def inline?
23
20
  mode == :inline
24
21
  end
25
- # steep:ignore:end
26
22
  end
27
23
 
28
24
  ##
@@ -32,10 +28,7 @@ module ReportPrint
32
28
  def initialize(output = $>, color: :auto)
33
29
  @output = output
34
30
  if color == :auto
35
- # Ignore block performing runtime type check.
36
- # steep:ignore:start
37
31
  color = output.respond_to?(:tty?) && output.tty?
38
- # steep:ignore:end
39
32
  end
40
33
  @rainbow = Rainbow::Wrapper.new(color)
41
34
 
@@ -47,9 +40,12 @@ module ReportPrint
47
40
  inline_separator: "",
48
41
  next_inline_separator: nil,
49
42
  after: nil,
50
- start_of_line: false,
51
- start_of_block: true
43
+ start_of_line: true,
44
+ start_of_block: true,
45
+ start_of_output: true
52
46
  ]
47
+
48
+ @options = ScopedOptions.new(ReportPrint.report_print_options)
53
49
  end
54
50
 
55
51
  ##
@@ -60,7 +56,14 @@ module ReportPrint
60
56
  def rp(object)
61
57
  case object
62
58
  when Object
63
- object.report_print(self)
59
+ if @seen.include?(object.__id__)
60
+ object.report_print_cycle(self)
61
+ else
62
+ if options_for(object)[:detect_cycles]
63
+ @seen.add(object.__id__)
64
+ end
65
+ object.report_print(self)
66
+ end
64
67
  else
65
68
  write("BasicObject", color: :bright_yellow)
66
69
  end
@@ -120,7 +123,8 @@ module ReportPrint
120
123
  if @state.inline?
121
124
  set_state(
122
125
  start_of_line: @state.start_of_line && result.start_of_line,
123
- start_of_block: @state.start_of_block && result.start_of_block
126
+ start_of_block: @state.start_of_block && result.start_of_block,
127
+ start_of_output: @state.start_of_output && result.start_of_output
124
128
  )
125
129
  if @state.next_inline_separator != result.next_inline_separator
126
130
  # If the inner inline state is requesting a separator, then that
@@ -129,7 +133,8 @@ module ReportPrint
129
133
  end
130
134
  else
131
135
  set_state(
132
- start_of_block: @state.start_of_block && result.start_of_block
136
+ start_of_block: @state.start_of_block && result.start_of_block,
137
+ start_of_output: @state.start_of_output && result.start_of_output
133
138
  )
134
139
  end
135
140
  end
@@ -167,7 +172,8 @@ module ReportPrint
167
172
  )
168
173
 
169
174
  set_state(
170
- start_of_block: @state.start_of_block && result.start_of_block
175
+ start_of_block: @state.start_of_block && result.start_of_block,
176
+ start_of_output: @state.start_of_output && result.start_of_output
171
177
  )
172
178
 
173
179
  did_write = !result.start_of_block
@@ -205,7 +211,7 @@ module ReportPrint
205
211
  # first concatenated into a single string, as in `IO#write`. Meaning no
206
212
  # separators or line breaks will be rendered between them.
207
213
  def write(*strings, color: nil)
208
- if @state.start_of_line
214
+ if @state.start_of_line && !@state.start_of_output
209
215
  unless @state.start_of_block
210
216
  @output.write(@state.separator)
211
217
  end
@@ -226,12 +232,14 @@ module ReportPrint
226
232
  set_state(
227
233
  start_of_line: false,
228
234
  start_of_block: false,
235
+ start_of_output: false,
229
236
  next_inline_separator: @state.inline_separator
230
237
  )
231
238
  else
232
239
  set_state(
233
240
  start_of_block: false,
234
- start_of_line: true
241
+ start_of_line: true,
242
+ start_of_output: false
235
243
  )
236
244
  end
237
245
  end
@@ -309,13 +317,13 @@ module ReportPrint
309
317
  end
310
318
  end
311
319
 
312
- def unless_seen(object)
313
- if @seen.include?(object.__id__)
314
- write_header(object)
315
- else
316
- @seen.add(object.__id__)
317
- yield
318
- end
320
+ ##
321
+ # Fetch the options which are set for the class of `object`.
322
+ #
323
+ # See Api#report_print_options for more details about the available
324
+ # options.
325
+ def options_for(object)
326
+ @options.options_for(object.class)
319
327
  end
320
328
 
321
329
  private
@@ -1,14 +1,5 @@
1
1
  module ReportPrint
2
2
  module Refinements
3
- refine Object.singleton_class do
4
- def report_print_inspect!(color: nil)
5
- define_method(:report_print) do |rp|
6
- # @type self: Object
7
- rp.write(inspect, color:)
8
- end
9
- end
10
- end
11
-
12
3
  refine Module do
13
4
  def short_class_name
14
5
  name.sub(/^.*::/, "")
@@ -0,0 +1,21 @@
1
+ module ReportPrint
2
+ class ScopedOptions
3
+ def initialize(global_options)
4
+ @global_options = global_options
5
+ @cache = {
6
+ Object => Object.report_print_options,
7
+ BasicObject => {}
8
+ }
9
+ end
10
+
11
+ def options_for(klass)
12
+ @global_options.merge(self_options_for(klass).compact)
13
+ end
14
+
15
+ private def self_options_for(klass)
16
+ @cache[klass] ||= (
17
+ self_options_for(klass.superclass).merge(klass.report_print_options)
18
+ )
19
+ end
20
+ end
21
+ end
@@ -1,3 +1,3 @@
1
1
  module ReportPrint
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/report_print.rb CHANGED
@@ -1,9 +1,11 @@
1
1
  require_relative "report_print/version"
2
2
  require_relative "report_print/refinements"
3
+ require_relative "report_print/api"
4
+ require_relative "report_print/scoped_options"
3
5
  require_relative "report_print/printer"
4
6
  require_relative "report_print/core_extensions"
5
7
  require_relative "report_print/dsl"
6
8
 
7
- module ReportPrint; end
8
-
9
- Kernel.prepend(ReportPrint::Dsl)
9
+ module ReportPrint
10
+ @report_print_options = {}
11
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: report_print
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benoit Hiller
@@ -28,11 +28,7 @@ description: |
28
28
 
29
29
  The name ReportPrint comes from the desire to output detailed reports of the program state at a given point in time, rather than merely inspecting an object.
30
30
 
31
- == Usage
32
-
33
- require 'report_print'
34
-
35
- rp object
31
+ After requiring simply use the global `rp` method to print objects like you do with `pp` or `ap`.
36
32
  email:
37
33
  - benoit.hiller@gmail.com
38
34
  executables: []
@@ -48,17 +44,19 @@ files:
48
44
  - gem_description.rdoc
49
45
  - lib/.document
50
46
  - lib/report_print.rb
47
+ - lib/report_print/api.rb
51
48
  - lib/report_print/core_extensions.rb
52
49
  - lib/report_print/dsl.rb
53
50
  - lib/report_print/printer.rb
54
51
  - lib/report_print/refinements.rb
52
+ - lib/report_print/scoped_options.rb
55
53
  - lib/report_print/version.rb
56
- homepage: https://github.com/BenoitHiller/report_print
54
+ homepage: https://benoithiller.github.io/report_print/
57
55
  licenses:
58
56
  - MIT-0
59
57
  metadata:
60
58
  allowed_push_host: https://rubygems.org
61
- homepage_uri: https://github.com/BenoitHiller/report_print
59
+ homepage_uri: https://benoithiller.github.io/report_print/
62
60
  source_code_uri: https://github.com/BenoitHiller/report_print
63
61
  rdoc_options: []
64
62
  require_paths: