object_inspector 0.2.0 → 0.3.0

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: 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