object_inspector 0.2.0 → 0.3.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: 8f80de3b28fe43b95e5fb12538a371807689aa29da9bf7d8a91eb9c4b8b4086c
4
- data.tar.gz: 775cecd797055357a8b4fb1c97d7c02a2821b8fbfbb0482f5a646f68da6a3710
3
+ metadata.gz: 93cdfccb3e1e30286035a4c152053794eb78ba6b99e3bf7b6d5679ca60c8f8fb
4
+ data.tar.gz: e551588d9bc978dd5676a14188787a55eed91b0e81c31c44479ac88559f350bc
5
5
  SHA512:
6
- metadata.gz: 3a0a0c78c42099cc7ea4b03276f6d06182ccad7e4ff657a4875cbe6690f7e277c3861fe7e5f00ebd8f7059516abb064f50ef78bf73ce26fd929f22a23143fddb
7
- data.tar.gz: 136d08a468531350650e48585f4471948cfdbd877ea4d462d07c11acdb381b276855c9520367dd1fc00ed8a21924b96a561e32b06d7dd51292a8705127221378
6
+ metadata.gz: 2ed62b8237dff20c6de7157c1c6475b08643396cc0fc1b71f2c334a562ca9253ee8da911949fc63c0549bad881e8f2704817c6c28bc265b6fd596ca5c5e47ad8
7
+ data.tar.gz: 6ff191c8ed79769432a2792b3c0c88d7ff6aae372d5ce323e455b6e890caecdb131dcf25ccdfd704fb9ec26bf416413330535d169dbe2d0f38d48c40485a3310
data/CHANGELOG.md CHANGED
@@ -1,18 +1,24 @@
1
- #### TODO
2
- * Add "placeholder" symbol (*) for scope exclusions.
3
- * Add gem defaults configuration.
1
+ ### 0.3.0 - 2018-04-14
2
+
3
+ - Remove optional dependency on ActiveSupport::StringInquirer. [Scopes are now objects](https://github.com/pdobb/object_inspector/blob/master/lib/object_inspector/scope.rb) that act like ActiveSupport::StringInquirer objects.
4
+ - Add ObjectInspector::Scope.join_flags helper method.
5
+ - Add ObjectInspector::Scope.join_info helper method.
6
+ - Scope: Show an out-of-scope-placeholder symbol (*) when predicate is not matched and a block is given.
7
+ - Scope: Add wild-card "all" scope that is always evaluated as true / a match.
8
+ - Add ability to specify multiple scopes. e.g. my_object.inspect(scope: %i[verbose complex])
9
+ - Add gem defaults configuration.
4
10
 
5
11
 
6
12
  ### 0.2.0 - 2018-04-12
7
13
 
8
- * Automatically inspect wrapped Objects, if applicable.
9
- * Use `display_name` if defined on object, in place of `inspect_name`.
10
- * Add on-the-fly inspect methods when Symbols are passed in to #inspect.
11
- * Update the `flags` and `info` demarcation symbols.
12
- * Add ObjectInspector::TemplatingFormatter, and use it as the new default since it's faster.
13
- * Rename ObjectInspector::DefaultFormatter to ObjectInspector::CombiningFormatter.
14
+ - Automatically inspect wrapped Objects, if applicable.
15
+ - Use `display_name` if defined on object, in place of `inspect_name`.
16
+ - Add on-the-fly inspect methods when Symbols are passed in to #inspect.
17
+ - Update the `flags` and `info` demarcation symbols.
18
+ - Add ObjectInspector::TemplatingFormatter, and use it as the new default since it's faster.
19
+ - Rename ObjectInspector::DefaultFormatter to ObjectInspector::CombiningFormatter.
14
20
 
15
21
 
16
22
  ### 0.1.0 - 2018-04-09
17
23
 
18
- * Initial release!
24
+ - Initial release!
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- object_inspector (0.1.0)
4
+ object_inspector (0.3.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -20,6 +20,7 @@ GEM
20
20
  builder
21
21
  minitest (>= 5.0)
22
22
  ruby-progressbar
23
+ object_identifier (0.1.0)
23
24
  pry (0.11.3)
24
25
  coderay (~> 1.1.0)
25
26
  method_source (~> 0.9.0)
@@ -43,6 +44,7 @@ DEPENDENCIES
43
44
  byebug (~> 10.0)
44
45
  minitest (~> 5.0)
45
46
  minitest-reporters (~> 1.2)
47
+ object_identifier (~> 0.1)
46
48
  object_inspector!
47
49
  pry (~> 0.11)
48
50
  pry-byebug (~> 3.6)
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # ObjectInspector
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/object_inspector.svg)](https://badge.fury.io/rb/object_inspector)
4
- [![Build Status](https://travis-ci.org/objects-on-rails/display-case.svg?branch=master)](https://travis-ci.org/objects-on-rails/display-case)
4
+ [![Build Status](https://travis-ci.org/pdobb/object_inspector.svg?branch=master)](https://travis-ci.org/pdobb/object_inspector)
5
5
  [![Test Coverage](https://api.codeclimate.com/v1/badges/34e821263d9e0c33d536/test_coverage)](https://codeclimate.com/github/pdobb/object_inspector/test_coverage)
6
6
  [![Maintainability](https://api.codeclimate.com/v1/badges/34e821263d9e0c33d536/maintainability)](https://codeclimate.com/github/pdobb/object_inspector/maintainability)
7
7
 
@@ -32,6 +32,24 @@ Tested MRI Ruby Versions:
32
32
  * 2.3.7
33
33
  * 2.4.4
34
34
  * 2.5.1
35
+ * edge
36
+
37
+
38
+ ## Configuration
39
+
40
+ Global/default values for ObjectInspector can be configured via the ObjectInspector::Configuration object.
41
+
42
+ _Note: In a Rails app, the following would go in e.g. `config/initializers/object_inspector.rb`_
43
+
44
+ ```ruby
45
+ # Default values are shown.
46
+ ObjectInspector.configure do |config|
47
+ config.wild_card_scope = "all"
48
+ config.out_of_scope_placeholder = "*"
49
+ config.flags_separator = " / "
50
+ config.info_separator = " | "
51
+ end
52
+ ```
35
53
 
36
54
 
37
55
  ## Usage
@@ -60,13 +78,13 @@ class MyObject
60
78
  def inspect
61
79
  ObjectInspector::Inspector.inspect(self,
62
80
  identification: "My Object",
63
- flags: "FLAG1",
81
+ flags: "FLAG1 / FLAG2",
64
82
  info: "INFO",
65
83
  name: "NAME")
66
84
  end
67
85
  end
68
86
 
69
- MyObject.new.inspect # => "<My Object(FLAG1) INFO :: NAME>"
87
+ MyObject.new.inspect # => "<My Object(FLAG1 / FLAG2) INFO :: NAME>"
70
88
  ```
71
89
 
72
90
  Or, define `inspect_identification`, `inspect_flags`, `inspect_info`, and `inspect_name` as either public or private methods on Object.
@@ -80,12 +98,12 @@ class MyObject
80
98
  private
81
99
 
82
100
  def inspect_identification; "My Object" end
83
- def inspect_flags; "FLAG1" end
101
+ def inspect_flags; "FLAG1 / FLAG2" end
84
102
  def inspect_info; "INFO" end
85
103
  def inspect_name; "NAME" end
86
104
  end
87
105
 
88
- MyObject.new.inspect # => "<My Object(FLAG1) INFO :: NAME>"
106
+ MyObject.new.inspect # => "<My Object(FLAG1 / FLAG2) INFO :: NAME>"
89
107
  ```
90
108
 
91
109
 
@@ -118,7 +136,7 @@ end
118
136
  MyObject.new.inspect # => "<My Object(FLAG1) INFO :: NAME>"
119
137
  ```
120
138
 
121
- Or, define `inspect_identification`, `inspect_flags`, `inspect_info`, and `inspect_name` in Object.
139
+ Or, define `inspect_identification`, `inspect_flags`, `inspect_info`, and `inspect_name` (or `display_name`) in Object.
122
140
 
123
141
  ```ruby
124
142
  class MyObject
@@ -127,61 +145,181 @@ class MyObject
127
145
  private
128
146
 
129
147
  def inspect_identification; "My Object" end
130
- def inspect_flags; "FLAG1" end
148
+ def inspect_flags; "FLAG1 / FLAG2" end
131
149
  def inspect_info; "INFO" end
132
- def inspect_name; "NAME" end
150
+ def inspect_name; "NAME" end # Or: def display_name; "NAME" end
133
151
  end
134
152
 
135
- MyObject.new.inspect # => "<My Object(FLAG1) INFO :: NAME>"
153
+ MyObject.new.inspect # => "<My Object(FLAG1 / FLAG2) INFO :: NAME>"
136
154
  ```
137
155
 
138
156
 
139
- ## On-the-fly Inspect Methods
157
+ ## Scopes
140
158
 
141
- When passed as an option (as opposed to being called via an Object-defined method) symbols will be called/evaluated on Object on the fly.
159
+ Use the `scope` option to define the scope of the `inspect_*` methods. The supplied value will be wrapped by the ObjectInspector::Scope helper object.
160
+ The default value is `ObjectInspector::Scope.new(:self)`.
161
+
162
+
163
+ ### Scope Names
164
+
165
+ ObjectInspector::Scope acts like [ActiveSupport::StringInquirer](http://api.rubyonrails.org/classes/ActiveSupport/StringInquirer.html). This is a prettier way to test for a given type of "scope" within objects.
166
+
167
+ The ObjectInspector::Scope objects in these examples are the same as specifying `<scope_name>` like this:
142
168
 
143
169
  ```ruby
144
- class MyObject
145
- include ObjectInspector::InspectorsHelper
170
+ my_object.inspect(scope: <scope_name>)
171
+ ```
146
172
 
147
- def my_method1; "Result1" end
148
- def my_method2; "Result2" end
149
173
 
150
- def inspect_info; :my_method2 end
151
- end
174
+ Options:
175
+ - `:self` (Default) -- Is meant to confine object interrogation to self (don't interrogate neighboring objects).
176
+ - `:all` -- Is meant to match on all scopes, regardless of their name.
177
+ - `<custom>` -- Anything else that makes sense for the object to key on.
152
178
 
153
- MyObject.new.inspect(info: "my_method1") # => "<MyObject my_method1>"
154
- MyObject.new.inspect(info: :my_method2) # => "<MyObject Result2>"
155
- MyObject.new.inspect # => "<MyObject my_method2>"
179
+ ```ruby
180
+ scope = ObjectInspector::Scope.new
181
+ scope.self? # => true
182
+ scope.verbose? # => false
183
+ scope.complex? # => false
184
+ ```
185
+
186
+
187
+ #### Multiple Scope Names
188
+
189
+ It is also possible to pass in multiple scope names to match on.
190
+
191
+ ```ruby
192
+ scope = ObjectInspector::Scope.new(%i[verbose complex])
193
+ scope.self? # => false
194
+ scope.verbose? # => true
195
+ scope.complex? # => true
196
+ ```
197
+
198
+
199
+ #### The "Wild Card" Scope
200
+
201
+ Finally, `:all` is a "wild card" scope name, and will match on all scope names.
202
+
203
+ ```ruby
204
+ scope = ObjectInspector::Scope.new(:all)
205
+ scope.self? # => true
206
+ scope.verbose? # => true
207
+ scope.complex? # => true
208
+ ```
209
+
210
+
211
+ ### Scope blocks
212
+
213
+ Passing a block to a scope predicate falls back to the out-of-scope placeholder (`*` by default) if the scope does not match.
214
+
215
+ ```ruby
216
+ scope = ObjectInspector::Scope.new(:verbose)
217
+ scope.verbose? { "MATCH" } # => "MATCH"
218
+ scope.complex? { "MATCH" } # => "*"
219
+ ```
220
+
221
+
222
+ ### Scope Joiners
223
+
224
+ ObjectInspector::Scope also offers helper methods for uniformly joining inspect elements:
225
+ - `join_flags` -- Joins flags with ` / ` by default
226
+ - `join_info` -- Joins info items with ` | ` by default
227
+
228
+ ```ruby
229
+ scope = ObjectInspector::Scope.new(:verbose)
230
+ scope.join_flags([1, 2, 3]) # => "1 / 2 / 3"
231
+ scope.join_info([1, 2, 3]) # => "1 | 2 | 3"
156
232
  ```
157
233
 
158
234
 
159
- #### Scope
235
+ ### Conversion to ObjectInspector::Scope
160
236
 
161
- Use the `scope` option to define the scope of the `inspect_*` methods.
237
+ ObjectInspector::Conversions.Scope() is available for proper conversion to ObjectInspector::Scope objects. Though this should rarely be necessary as conversion is performed automatically when calling `<my_object>.inspect(scope: <scope_name>)`.
238
+
239
+ ```ruby
240
+ ObjectInspector::Conversions.Scope(:self)
241
+ # => #<ObjectInspector::Scope:0x007ff78ab8e7f8 @name="self">
242
+
243
+ scope = ObjectInspector::Scope.new(:verbose)
244
+ result = ObjectInspector::Conversions.Scope(scope)
245
+ # => #<ObjectInspector::Scope:0x007ff78ac9c140 @name="verbose">
246
+
247
+ scope.object_id == result.object_id # => true
248
+ ```
162
249
 
163
- If ActiveSupport::StringInquirer is defined then the default `scope` is `"self".inquiry`.
164
- The default value is `:self` if ActiveSupport::StringInquirer is not defined.
250
+
251
+ ## Full Example
165
252
 
166
253
  ```ruby
167
254
  class MyObject
168
255
  include ObjectInspector::InspectorsHelper
169
256
 
170
- def inspect_flags(scope:, separator: " / ".freeze)
171
- flags = ["FLAG1"]
257
+ attr_reader :name,
258
+ :a2
259
+
260
+ def initialize(name, a2 = 2)
261
+ @name = name
262
+ @a2 = a2
263
+ end
264
+
265
+ def associated_object1
266
+ OpenStruct.new(flags: "AO1_FLAG1")
267
+ end
268
+
269
+ def associated_object2
270
+ OpenStruct.new(flags: "AO2_FLAG1")
271
+ end
272
+
273
+ private
172
274
 
173
- # If ActiveSupport::StringInquirer is defined, use this:
174
- # flags << "FLAG2" if scope.all?
275
+ def inspect_identification
276
+ identify(:a2)
277
+ end
175
278
 
176
- # If ActiveSupport::StringInquirer is not defined, use this:
177
- flags << "FLAG2" if scope == :all
279
+ def inspect_flags(scope:)
280
+ flags = ["DEFAULT_FLAG"]
178
281
 
179
- flags.join(separator)
282
+ flags <<
283
+ scope.verbose? {
284
+ [
285
+ associated_object1.flags,
286
+ associated_object2.flags,
287
+ ]
288
+ }
289
+
290
+ scope.join_flags(flags)
291
+ end
292
+
293
+ def inspect_info(scope:)
294
+ info = ["Default Info"]
295
+ info << "Complex Info" if scope.complex?
296
+ info << scope.verbose? { "Verbose Info" }
297
+
298
+ scope.join_info(info)
299
+ end
300
+
301
+ # Or `def inspect_name`
302
+ def display_name
303
+ name
180
304
  end
181
305
  end
182
306
 
183
- MyObject.new.inspect # => "<MyObject(FLAG1)>"
184
- MyObject.new.inspect(scope: :all) # => "<MyObject(FLAG1 / FLAG2)>"
307
+ my_object = MyObject.new("Name")
308
+
309
+ my_object.inspect
310
+ # => "<MyObject[a2:2](DEFAULT_FLAG / *) Default Info | * :: Name>"
311
+
312
+ my_object.inspect(scope: :complex)
313
+ # => "<MyObject[a2:2](DEFAULT_FLAG / *) Default Info | Complex Info | * :: Name>"
314
+
315
+ my_object.inspect(scope: :verbose)
316
+ # => "<MyObject[a2:2](DEFAULT_FLAG / AO1_FLAG1 / AO2_FLAG1) Default Info | Verbose Info :: Name>"
317
+
318
+ my_object.inspect(scope: %i[self complex verbose])
319
+ # => "<MyObject[a2:2](DEFAULT_FLAG / AO1_FLAG1 / AO2_FLAG1) Default Info | Complex Info | Verbose Info :: Name>"
320
+
321
+ my_object.inspect(scope: :all)
322
+ # => "<MyObject[a2:2](DEFAULT_FLAG / AO1_FLAG1 / AO2_FLAG1) Default Info | Complex Info | Verbose Info :: Name>"
185
323
  ```
186
324
 
187
325
 
@@ -207,17 +345,37 @@ class MyWrappedObject
207
345
 
208
346
  private
209
347
 
210
- def inspect_flags; "FLAG1" end
348
+ def inspect_flags; "FLAG1 / FLAG2" end
211
349
  def inspect_info; "INFO" end
212
350
  end
213
351
 
214
352
  MyWrapperObject.new.inspect
215
- # => "<MyWrapperObject(WRAPPER_FLAG1)> ⇨ <MyWrappedObject(FLAG1) INFO>"
353
+ # => "<MyWrapperObject(WRAPPER_FLAG1)> ⇨ <MyWrappedObject(FLAG1 / FLAG2) INFO>"
216
354
  ```
217
355
 
218
356
  This feature is recursive.
219
357
 
220
358
 
359
+ ## On-the-fly Inspect Methods
360
+
361
+ When passed as an option (as opposed to being called via an Object-defined method) symbols will be called/evaluated on Object on the fly.
362
+
363
+ ```ruby
364
+ class MyObject
365
+ include ObjectInspector::InspectorsHelper
366
+
367
+ def my_method1; "Result1" end
368
+ def my_method2; "Result2" end
369
+
370
+ def inspect_info; :my_method2 end
371
+ end
372
+
373
+ MyObject.new.inspect(info: "my_method1") # => "<MyObject my_method1>"
374
+ MyObject.new.inspect(info: :my_method2) # => "<MyObject Result2>"
375
+ MyObject.new.inspect # => "<MyObject my_method2>"
376
+ ```
377
+
378
+
221
379
  ## Custom Formatters
222
380
 
223
381
  A custom inspect formatter can be defined by implementing the interface defined by [ObjectInspector::BaseFormatter](https://github.com/pdobb/object_inspector/blob/master/lib/object_inspector/formatters/base_formatter.rb) and then passing that into ObjectInspector::Inspector.new.
@@ -235,18 +393,19 @@ class MyObject
235
393
  def inspect
236
394
  super(formatter: MyCustomFormatter,
237
395
  identification: "IDENTIFICATION",
238
- flags: "FLAG1 | FLAG2",
396
+ flags: "FLAG1 / FLAG2",
239
397
  info: "INFO",
240
398
  name: "NAME")
241
399
  end
242
400
  end
243
401
 
244
402
  MyObject.new.inspect
245
- # => "[IDENTIFICATION Flags: FLAG1 | FLAG2 -- Info: INFO -- Name: NAME]"
403
+ # => "[IDENTIFICATION Flags: FLAG1 / FLAG2 -- Info: INFO -- Name: NAME]"
246
404
  ```
247
405
 
248
- See also: [ObjectInspector::TemplatingFormatter].
249
- See also: [ObjectInspector::CombiningFormatter].
406
+ See examples:
407
+ - [ObjectInspector::TemplatingFormatter]
408
+ - [ObjectInspector::CombiningFormatter]
250
409
 
251
410
 
252
411
  ## Performance
@@ -283,6 +442,7 @@ play scripts/benchmarking/formatters.rb
283
442
  # == Done
284
443
  ```
285
444
 
445
+
286
446
  #### Benchmarking Custom Formatters
287
447
 
288
448
  Custom Formatters may be similarly gauged for comparison by adding them to the `custom_formatter_klasses` array before playing the script.
@@ -312,23 +472,26 @@ class MyObject
312
472
  include ObjectInspector::InspectorsHelper
313
473
 
314
474
  def my_method1
315
- "Result1"
475
+ 1
316
476
  end
317
477
 
318
478
  def my_method2
319
- "Result2"
479
+ 2
320
480
  end
321
481
 
322
482
  private
323
483
 
324
- def inspect_identification; identify(:my_method1, :my_method2) end
325
- def inspect_flags; "FLAG1" end
484
+ def inspect_identification
485
+ identify(:my_method1, :my_method2)
486
+ end
487
+
488
+ def inspect_flags; "FLAG1 / FLAG2" end
326
489
  def inspect_info; "INFO" end
327
490
  def inspect_name; "NAME" end
328
491
  end
329
492
 
330
493
  MyObject.new.inspect
331
- # => "<MyObject[my_method1:Result1, my_method2:Result2](FLAG1) INFO :: NAME>"
494
+ # => "<MyObject[my_method1:1, my_method2:2](FLAG1 / FLAG2) INFO :: NAME>"
332
495
  ```
333
496
 
334
497
 
data/bin/console CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  require "bundler/setup"
4
4
  require "object_inspector"
5
+ require "object_identifier"
6
+ require "ostruct"
5
7
 
6
8
  # You can add fixtures and/or initialization code here to make experimenting
7
9
  # with your gem easier. You can also use a different console, if you like.
@@ -0,0 +1,22 @@
1
+ module ObjectInspector
2
+ # ObjectInspector::Conversions defines conversion functions used by
3
+ # ObjectInspector.
4
+ module Conversions
5
+
6
+ module_function
7
+
8
+ # Convert the passed in value to an {ObjectInspector::Scope} object.
9
+ # Just returns the pass in value if it already is an
10
+ # {ObjectInspector::Scope} object.
11
+ #
12
+ # @return [ObjectInspector::Scope]
13
+ def Scope(value)
14
+ case value
15
+ when ObjectInspector::Scope
16
+ value
17
+ else
18
+ ObjectInspector::Scope.new(value)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -5,26 +5,18 @@ module ObjectInspector
5
5
  #
6
6
  # @attr object [Object] the object being inspected
7
7
  # @attr scope [Symbol] Object inspection type. For example:
8
- # :self (default) -- Means: Only interrogate self; Don't interrogate
9
- # neighboring objects
10
- # :all -- Means: Interrogate self as well as neighboring objects
11
- # <custom> -- Any value that {#object} recognizes can mean anything
12
- # that makes sense for {#object}
13
- # @attr formatter [ObjectInspector::BaseFormatter] the formatter object to use
14
- # for combining the output of into the inspect String
15
- # @attr kargs [Hash] options to be sent to {#object}
8
+ # :self (default) -- Means: Only interrogate self. Don't visit neighbors.
9
+ # <custom> -- Anything else that makes sense for {#object} to key on
10
+ # @attr formatter [ObjectInspector::BaseFormatter] the formatter object type
11
+ # to use for formatting the inspect String
12
+ # @attr kargs [Hash] options to be sent to {#object} via the
13
+ # {ObjectInspector::ObjectInterrogator} when calling the `inspect_*` methods
16
14
  class Inspector
17
15
  attr_reader :object,
18
16
  :scope,
19
17
  :formatter_klass,
20
18
  :kargs
21
19
 
22
- # The prefix for all methods called on {#object} for inspect
23
- # details/strings.
24
- def self.object_inspect_method_prefix
25
- "inspect".freeze
26
- end
27
-
28
20
  # Shortcuts the instantiation -> {#to_s} flow that would normally be
29
21
  # required to use ObjectInspector::Inspector.
30
22
  #
@@ -40,12 +32,7 @@ module ObjectInspector
40
32
  **kargs)
41
33
  @object = object
42
34
  @formatter_klass = formatter
43
- @scope =
44
- if ObjectInspector.use_string_inquirers?
45
- scope.to_s.inquiry
46
- else
47
- scope.to_sym
48
- end
35
+ @scope = Conversions.Scope(scope)
49
36
  @kargs = kargs
50
37
  end
51
38
 
@@ -56,7 +43,7 @@ module ObjectInspector
56
43
  formatter.call
57
44
  end
58
45
 
59
- # Generate the inspect String for a wrapped object, if applicable.
46
+ # Generate the inspect String for the wrapped object, if present.
60
47
  #
61
48
  # @return [String] if {#object_is_a_wrapper}
62
49
  # @return [NilClass] if not {#object_is_a_wrapper}
@@ -110,7 +97,7 @@ module ObjectInspector
110
97
  end
111
98
 
112
99
  # @return [String] if `key` is found in {#kargs} or if {#object} responds to
113
- # `#{object_inspect_method_prefix}_#{key}` (e.g. `inspect_flags`)
100
+ # `#{object_inspet_method_name}` (e.g. `inspect_flags`)
114
101
  # @return [NilClass] if not found in {#kargs} or {#object}
115
102
  def value(key:)
116
103
  return_value =
@@ -141,11 +128,13 @@ module ObjectInspector
141
128
  # Attempt to call `inspect_*` on {#object} based on the passed in `name`.
142
129
  #
143
130
  # @return [String] if {#object} responds to
144
- # `#{object_inspect_method_prefix}_#{name}` (e.g. `inspect_flags`)
131
+ # `#{object_inspet_method_name}` (e.g. `inspect_flags`)
145
132
  # @return [NilClass] if not found on {#object}
146
- def interrogate_object_inspect_method(name)
133
+ def interrogate_object_inspect_method(
134
+ name,
135
+ prefix: ObjectInspector.configuration.inspect_method_prefix)
147
136
  interrogate_object(
148
- method_name: build_inspet_method_name(name),
137
+ method_name: object_inspet_method_name(name, prefix: prefix),
149
138
  kargs: object_method_keyword_arguments)
150
139
  end
151
140
 
@@ -159,12 +148,10 @@ module ObjectInspector
159
148
  interrogator.call
160
149
  end
161
150
 
162
- def build_inspet_method_name(name)
163
- "#{object_inspect_method_prefix}_#{name}"
164
- end
165
-
166
- def object_inspect_method_prefix
167
- self.class.object_inspect_method_prefix
151
+ def object_inspet_method_name(
152
+ name,
153
+ prefix: ObjectInspector.configuration.inspect_method_prefix)
154
+ "#{prefix}_#{name}"
168
155
  end
169
156
 
170
157
  def object_method_keyword_arguments
@@ -22,13 +22,21 @@ module ObjectInspector
22
22
  def call
23
23
  return unless object_responds_to_method_name?
24
24
 
25
+ if object.method(method_name).arity != 0
26
+ call_with_kargs
27
+ else
28
+ object.send(method_name)
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def call_with_kargs
25
35
  object.send(method_name, **kargs)
26
36
  rescue ArgumentError
27
37
  object.send(method_name)
28
38
  end
29
39
 
30
- private
31
-
32
40
  def object_responds_to_method_name?(include_private: true)
33
41
  object.respond_to?(method_name, include_private)
34
42
  end
@@ -0,0 +1,82 @@
1
+ module ObjectInspector
2
+ # ObjectInspector::Scope defines a predicate method that matches {#name} and
3
+ # responds with `true`. This is a prettier way to test for a given type of
4
+ # "scope" within objects.
5
+ #
6
+ # @see ActiveSupport::StringInquirer
7
+ # http://api.rubyonrails.org/classes/ActiveSupport/StringInquirer.html
8
+ #
9
+ # @attr names [Array<#to_s>]
10
+ class Scope
11
+ attr_reader :names
12
+
13
+ def initialize(names = %w[self])
14
+ @names = Array(names).map { |name| String(name) }
15
+ end
16
+
17
+ # Join the passed-in flags with the passed in separator.
18
+ #
19
+ # @param items [Array<#to_s>]
20
+ # @param separator [#to_s] (ObjectInspector.configuration.flags_separator)
21
+ def join_flags(flags,
22
+ separator: ObjectInspector.configuration.flags_separator)
23
+ Array(flags).join(separator)
24
+ end
25
+
26
+ # Join the passed-in items with the passed in separator.
27
+ #
28
+ # @param items [Array<#to_s>]
29
+ # @param separator [#to_s] (ObjectInspector.configuration.info_separator)
30
+ def join_info(items,
31
+ separator: ObjectInspector.configuration.info_separator)
32
+ Array(items).join(separator)
33
+ end
34
+
35
+ private
36
+
37
+ def method_missing(method_name, *args, &block)
38
+ if method_name[-1] == "?"
39
+ scope_name = method_name[0..-2]
40
+ evaluate_match(scope_name, &block)
41
+ else
42
+ super
43
+ end
44
+ end
45
+
46
+ def evaluate_match(scope_name, &block)
47
+ is_a_match = match?(scope_name)
48
+
49
+ if block
50
+ evaluate_block_if(is_a_match, &block)
51
+ else
52
+ is_a_match
53
+ end
54
+ end
55
+
56
+ def evaluate_block_if(condition, &block)
57
+ if condition
58
+ block.call
59
+ else
60
+ ObjectInspector.configuration.out_of_scope_placeholder
61
+ end
62
+ end
63
+
64
+ def match?(scope_name)
65
+ any_names_match?(scope_name) ||
66
+ wild_card_scope?
67
+ end
68
+
69
+ def wild_card_scope?
70
+ @is_wild_card_scope ||=
71
+ any_names_match?(ObjectInspector.configuration.wild_card_scope)
72
+ end
73
+
74
+ def any_names_match?(other_name)
75
+ @names.any? { |name| name == other_name }
76
+ end
77
+
78
+ def respond_to_missing?(method_name, include_private = false)
79
+ method_name[-1] == "?" || super
80
+ end
81
+ end
82
+ end
@@ -1,3 +1,3 @@
1
1
  module ObjectInspector
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -1,19 +1,63 @@
1
1
  # ObjectInspector is the base namespace for all modules/classes related to the
2
2
  # object_inspector gem.
3
3
  module ObjectInspector
4
- @@use_string_inquirers = nil
4
+ class << self
5
+ attr_writer :configuration
6
+ end
7
+
8
+ def self.configuration
9
+ @configuration ||= Configuration.new
10
+ end
11
+
12
+ def self.configure
13
+ yield(configuration)
14
+ end
15
+
16
+ def self.reset_configuration
17
+ @configuration = Configuration.new
18
+ end
19
+
20
+ class Configuration
21
+ attr_reader :wild_card_scope,
22
+ :out_of_scope_placeholder,
23
+ :flags_separator,
24
+ :info_separator,
25
+ :inspect_method_prefix
26
+
27
+ def initialize
28
+ @wild_card_scope = "all".freeze
29
+ @out_of_scope_placeholder = "*".freeze
30
+ @flags_separator = " / ".freeze
31
+ @info_separator = " | ".freeze
32
+ @inspect_method_prefix = "inspect".freeze
33
+ end
34
+
35
+ def wild_card_scope=(value)
36
+ @wild_card_scope = value.to_s.freeze
37
+ end
38
+
39
+ def out_of_scope_placeholder=(value)
40
+ @out_of_scope_placeholder = value.to_s.freeze
41
+ end
42
+
43
+ def flags_separator=(value)
44
+ @flags_separator = value.to_s.freeze
45
+ end
46
+
47
+ def info_separator=(value)
48
+ @info_separator = value.to_s.freeze
49
+ end
5
50
 
6
- def self.use_string_inquirers?
7
- if @@use_string_inquirers.nil?
8
- @@use_string_inquirers = !!defined?(ActiveSupport::StringInquirer)
9
- else
10
- @@use_string_inquirers
51
+ def inspect_method_prefix=(value)
52
+ @inspect_method_prefix = value.to_s.freeze
11
53
  end
12
54
  end
13
55
  end
14
56
 
15
57
  require "object_inspector/version"
58
+ require "object_inspector/conversions"
16
59
  require "object_inspector/inspector"
60
+ require "object_inspector/scope"
17
61
  require "object_inspector/inspectors_helper"
18
62
  require "object_inspector/object_interrogator"
19
63
  require "object_inspector/formatters/base_formatter"
@@ -33,11 +33,11 @@ Gem::Specification.new do |spec|
33
33
  spec.add_development_dependency "bundler", "~> 1.16"
34
34
  spec.add_development_dependency "rake", "~> 10.0"
35
35
  spec.add_development_dependency "minitest", "~> 5.0"
36
+ spec.add_development_dependency "minitest-reporters", "~> 1.2"
36
37
  spec.add_development_dependency "simplecov", "~> 0.16"
37
38
  spec.add_development_dependency "byebug", "~> 10.0"
38
39
  spec.add_development_dependency "pry", "~> 0.11"
39
40
  spec.add_development_dependency "pry-byebug", "~> 3.6"
40
41
  spec.add_development_dependency "benchmark-ips", "~> 2.7"
41
- spec.add_development_dependency "minitest-reporters", "~> 1.2"
42
- # spec.add_development_dependency "object_identifier", "~> 0.1" # Add when new version is released
42
+ spec.add_development_dependency "object_identifier", "~> 0.1"
43
43
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: object_inspector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Dobbins
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-13 00:00:00.000000000 Z
11
+ date: 2018-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-reporters
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.2'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: simplecov
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -123,19 +137,19 @@ dependencies:
123
137
  - !ruby/object:Gem::Version
124
138
  version: '2.7'
125
139
  - !ruby/object:Gem::Dependency
126
- name: minitest-reporters
140
+ name: object_identifier
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
143
  - - "~>"
130
144
  - !ruby/object:Gem::Version
131
- version: '1.2'
145
+ version: '0.1'
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
150
  - - "~>"
137
151
  - !ruby/object:Gem::Version
138
- version: '1.2'
152
+ version: '0.1'
139
153
  description: ObjectInspector takes Object#inspect to the next level. Specify any combination
140
154
  of identification attributes, flags, info, and/or a name along with an optional
141
155
  self-definable scope option to represent an object in the console, in logging, etc.
@@ -156,12 +170,14 @@ files:
156
170
  - bin/console
157
171
  - bin/setup
158
172
  - lib/object_inspector.rb
173
+ - lib/object_inspector/conversions.rb
159
174
  - lib/object_inspector/formatters/base_formatter.rb
160
175
  - lib/object_inspector/formatters/combining_formatter.rb
161
176
  - lib/object_inspector/formatters/templating_formatter.rb
162
177
  - lib/object_inspector/inspector.rb
163
178
  - lib/object_inspector/inspectors_helper.rb
164
179
  - lib/object_inspector/object_interrogator.rb
180
+ - lib/object_inspector/scope.rb
165
181
  - lib/object_inspector/version.rb
166
182
  - object_inspector.gemspec
167
183
  - scripts/benchmarking/formatters.rb