object_inspector 0.9.0 → 1.0.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 +4 -4
- data/README.md +207 -57
- data/lib/object_inspector/conversions.rb +12 -4
- data/lib/object_inspector/formatters/base_formatter.rb +20 -21
- data/lib/object_inspector/formatters/combining_formatter.rb +2 -3
- data/lib/object_inspector/formatters/templating_formatter.rb +3 -6
- data/lib/object_inspector/inspect_behaviors.rb +36 -0
- data/lib/object_inspector/inspector.rb +79 -65
- data/lib/object_inspector/{object_interrogator.rb → interrogate_object.rb} +11 -8
- data/lib/object_inspector/scope.rb +40 -15
- data/lib/object_inspector/version.rb +4 -1
- data/lib/object_inspector.rb +22 -6
- metadata +5 -5
- data/lib/object_inspector/inspectors_helper.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd42799a69895e8a918436eaa6688090722f4dde5d406f34b36eae201459f82a
|
4
|
+
data.tar.gz: 1ea233bec14fddd0b57ffb797da6009471f8f9f989fee45f204af8813b70f59e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f30121bcdddfd33c7990197e4513eb44a84a487afc4f346a5823067760e2754aaf7ae0871ae58157ef45686de4a885e2db798e97e7a35671c5b0143fedafb11c
|
7
|
+
data.tar.gz: 4ed8d2ac33b52b4af28bc621a2e92fd429039c6951a2d8d10a38e866a9d101e2f18d24a60125fb189b367232293068c63a3ca0ec0bdaa1bb6df37119f26db5d0
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Object Inspector takes Object#inspect to the next level. Specify any combination of identification attributes, flags, issues, info, and/or a name along with an optional, self-definable scope option to represent objects. Great for the console, logging, etc.
|
7
7
|
|
8
|
-
Why? Because object inspection
|
8
|
+
Why? Because object inspection output should be uniform and easy to build, and its output should be easy to read! Consistency improves readability.
|
9
9
|
|
10
10
|
If you'd like to just jump into an example: [Full Example](#full-example).
|
11
11
|
|
@@ -60,6 +60,7 @@ Global/default values for Object Inspector can be configured via the [ObjectInsp
|
|
60
60
|
|
61
61
|
# Default values are shown. Customize to your liking.
|
62
62
|
ObjectInspector.configure do |config|
|
63
|
+
config.enabled = true
|
63
64
|
config.formatter_class = ObjectInspector::TemplatingFormatter
|
64
65
|
config.inspect_method_prefix = "inspect"
|
65
66
|
config.default_scope = ObjectInspector::Scope.new(:self)
|
@@ -84,7 +85,10 @@ class MyObject
|
|
84
85
|
end
|
85
86
|
end
|
86
87
|
|
87
|
-
MyObject.new.inspect
|
88
|
+
MyObject.new.inspect # => "<MyObject>"
|
89
|
+
|
90
|
+
MyObject.new # =>
|
91
|
+
<MyObject>
|
88
92
|
```
|
89
93
|
|
90
94
|
See: [Helper Usage](#helper-usage) for simpler usage.
|
@@ -106,8 +110,8 @@ class MyObject
|
|
106
110
|
end
|
107
111
|
end
|
108
112
|
|
109
|
-
MyObject.new
|
110
|
-
|
113
|
+
MyObject.new # =>
|
114
|
+
<My Object(FLAG1 / FLAG2) !!ISSUE1!! INFO :: NAME>
|
111
115
|
```
|
112
116
|
|
113
117
|
Or, define `inspect_identification`, `inspect_flags`, `inspect_issues`, `inspect_info`, and/or `inspect_name` (or `display_name`) as either public or private methods on Object.
|
@@ -127,27 +131,28 @@ class MyObject
|
|
127
131
|
def inspect_name = "NAME" # Or: def display_name = "NAME"
|
128
132
|
end
|
129
133
|
|
130
|
-
MyObject.new
|
131
|
-
|
134
|
+
MyObject.new # =>
|
135
|
+
<My Object(FLAG1 / FLAG2) !!ISSUE1 | ISSUE2!! INFO :: NAME>
|
132
136
|
```
|
133
137
|
|
134
138
|
## Helper Usage
|
135
139
|
|
136
|
-
To save some typing, include ObjectInspector::
|
140
|
+
To save some typing, include ObjectInspector::InspectBehaviors into an object and `ObjectInspector::Inspector.inspect` will be called on `self` automatically.
|
137
141
|
|
138
142
|
```ruby
|
139
143
|
class MyObject
|
140
|
-
include ObjectInspector::
|
144
|
+
include ObjectInspector::InspectBehaviors
|
141
145
|
end
|
142
146
|
|
143
|
-
MyObject.new
|
147
|
+
MyObject.new # =>
|
148
|
+
<MyObject>
|
144
149
|
```
|
145
150
|
|
146
151
|
To access the ObjectInspector::Inspector's options via the helper, call into `super`.
|
147
152
|
|
148
153
|
```ruby
|
149
154
|
class MyObject
|
150
|
-
include ObjectInspector::
|
155
|
+
include ObjectInspector::InspectBehaviors
|
151
156
|
|
152
157
|
def inspect
|
153
158
|
super(identification: "My Object",
|
@@ -158,15 +163,15 @@ class MyObject
|
|
158
163
|
end
|
159
164
|
end
|
160
165
|
|
161
|
-
MyObject.new
|
162
|
-
|
166
|
+
MyObject.new # =>
|
167
|
+
<My Object(FLAG1) !!ISSUE1 | ISSUE2!! INFO :: NAME>
|
163
168
|
```
|
164
169
|
|
165
170
|
Or, define `inspect_identification`, `inspect_flags`, `inspect_info`, and/or `inspect_name` (or `display_name`) in Object.
|
166
171
|
|
167
172
|
```ruby
|
168
173
|
class MyObject
|
169
|
-
include ObjectInspector::
|
174
|
+
include ObjectInspector::InspectBehaviors
|
170
175
|
|
171
176
|
private
|
172
177
|
|
@@ -177,8 +182,72 @@ class MyObject
|
|
177
182
|
def inspect_name = "NAME" # Or: def display_name = "NAME"
|
178
183
|
end
|
179
184
|
|
180
|
-
MyObject.new
|
181
|
-
|
185
|
+
MyObject.new # =>
|
186
|
+
<My Object(FLAG1) !!ISSUE1 | ISSUE2!! INFO :: NAME>
|
187
|
+
```
|
188
|
+
|
189
|
+
### Disabling ObjectInspector
|
190
|
+
|
191
|
+
You may disable / re-enable Object Inspector output (via the included helper method) for the current session:
|
192
|
+
|
193
|
+
```ruby
|
194
|
+
MyObject.new # =>
|
195
|
+
<My Object(FLAG1 / FLAG2) !!ISSUE1 | ISSUE2!! INFO :: NAME>
|
196
|
+
|
197
|
+
ObjectInspector.configuration.disable # =>
|
198
|
+
-> ObjectInspector disabled
|
199
|
+
MyObject.new # =>
|
200
|
+
#<MyObject:0x000000012332c458>
|
201
|
+
|
202
|
+
ObjectInspector.configuration.enable # =>
|
203
|
+
-> ObjectInspector enabled
|
204
|
+
MyObject.new # =>
|
205
|
+
<My Object(FLAG1 / FLAG2) !!ISSUE1 | ISSUE2!! INFO :: NAME>
|
206
|
+
```
|
207
|
+
|
208
|
+
Or, toggle current state:
|
209
|
+
|
210
|
+
```ruby
|
211
|
+
ObjectInspector.configuration.toggle; # =>
|
212
|
+
-> ObjectInspector disabled
|
213
|
+
|
214
|
+
ObjectInspector.configuration.toggle; # =>
|
215
|
+
-> ObjectInspector enabled
|
216
|
+
```
|
217
|
+
|
218
|
+
### Helper Inclusion
|
219
|
+
|
220
|
+
Instead of including `ObjectInspector::InspectBehaviors` directly, it may be useful to define your own mix-in.
|
221
|
+
|
222
|
+
```ruby
|
223
|
+
module ObjectInspectionBehaviors
|
224
|
+
include ObjectInspector::InspectBehaviors
|
225
|
+
|
226
|
+
# For defining #inspect chains.
|
227
|
+
def introspect
|
228
|
+
# { self => ... }
|
229
|
+
self
|
230
|
+
end
|
231
|
+
end
|
232
|
+
```
|
233
|
+
|
234
|
+
#### Usage:
|
235
|
+
|
236
|
+
```ruby
|
237
|
+
class MyObject
|
238
|
+
include ObjectInspectionBehaviors # 👀 Defined above.
|
239
|
+
|
240
|
+
private
|
241
|
+
|
242
|
+
def inspect_identification = "My Object"
|
243
|
+
def inspect_flags = "FLAG1 / FLAG2"
|
244
|
+
def inspect_issues = "ISSUE1 | ISSUE2"
|
245
|
+
def inspect_info = "INFO"
|
246
|
+
def inspect_name = "NAME" # Or: def display_name = "NAME"
|
247
|
+
end
|
248
|
+
|
249
|
+
MyObject.new # =>
|
250
|
+
<My Object(FLAG1) !!ISSUE1 | ISSUE2!! INFO :: NAME>
|
182
251
|
```
|
183
252
|
|
184
253
|
## Scopes
|
@@ -188,7 +257,7 @@ The default value is `ObjectInspector::Scope.new(:self)`.
|
|
188
257
|
|
189
258
|
### Scope Names
|
190
259
|
|
191
|
-
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.
|
260
|
+
ObjectInspector::Scope acts like an [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.
|
192
261
|
|
193
262
|
The ObjectInspector::Scope objects in these examples are the same as specifying `<scope_name>` like this:
|
194
263
|
|
@@ -216,9 +285,9 @@ It is also possible to pass in multiple scope names to match on.
|
|
216
285
|
|
217
286
|
```ruby
|
218
287
|
scope = ObjectInspector::Scope.new(%i[verbose complex])
|
219
|
-
scope.self?
|
220
|
-
scope.verbose?
|
221
|
-
scope.complex?
|
288
|
+
scope.self? # => false
|
289
|
+
scope.verbose? # => true
|
290
|
+
scope.complex? # => true
|
222
291
|
```
|
223
292
|
|
224
293
|
#### The "Wild Card" Scope
|
@@ -227,20 +296,22 @@ Finally, `:all` is a "wild card" scope name, and will match on all scope names.
|
|
227
296
|
|
228
297
|
```ruby
|
229
298
|
scope = ObjectInspector::Scope.new(:all)
|
230
|
-
scope.self?
|
231
|
-
scope.verbose?
|
232
|
-
scope.complex?
|
233
|
-
scope.all?
|
299
|
+
scope.self? # => true
|
300
|
+
scope.verbose? # => true
|
301
|
+
scope.complex? # => true
|
302
|
+
scope.all? # => true
|
234
303
|
```
|
235
304
|
|
305
|
+
_**NOTE**_: Calling `#inspect!` on an object that mixes in `ObjectInspector::InspectBehaviors` is equivalent to passing in the "wild card" scope.
|
306
|
+
|
236
307
|
### Scope blocks
|
237
308
|
|
238
309
|
Passing a block to a scope predicate falls back to the out-of-scope placeholder (`*` by default) if the scope does not match.
|
239
310
|
|
240
311
|
```ruby
|
241
312
|
scope = ObjectInspector::Scope.new(:verbose)
|
242
|
-
scope.verbose? { "MATCH" }
|
243
|
-
scope.complex? { "MATCH" }
|
313
|
+
scope.verbose? { "MATCH" } # => "MATCH"
|
314
|
+
scope.complex? { "MATCH" } # => "*"
|
244
315
|
```
|
245
316
|
|
246
317
|
### Scope Joiners
|
@@ -248,10 +319,10 @@ scope.complex? { "MATCH" } # => "*"
|
|
248
319
|
ObjectInspector::Scope also offers helper methods for uniformly joining inspect elements:
|
249
320
|
|
250
321
|
```ruby
|
251
|
-
join_name # Joins name parts with ` - ` by default
|
252
|
-
join_flags # Joins flags with ` / ` by default
|
253
|
-
join_issues # Joins issues with ` | ` by default
|
254
|
-
join_info # Joins info items with ` | ` by default
|
322
|
+
scope.join_name # Joins name parts with ` - ` by default
|
323
|
+
scope.join_flags # Joins flags with ` / ` by default
|
324
|
+
scope.join_issues # Joins issues with ` | ` by default
|
325
|
+
scope.join_info # Joins info items with ` | ` by default
|
255
326
|
```
|
256
327
|
|
257
328
|
For example:
|
@@ -268,7 +339,7 @@ scope.join_info([1, 2, 3, nil]) # => "1 | 2 | 3"
|
|
268
339
|
|
269
340
|
```ruby
|
270
341
|
class MyObject
|
271
|
-
include ObjectInspector::
|
342
|
+
include ObjectInspector::InspectBehaviors
|
272
343
|
|
273
344
|
attr_reader :name,
|
274
345
|
:a2
|
@@ -347,17 +418,20 @@ my_object.inspect(scope: %i[self complex verbose])
|
|
347
418
|
my_object.inspect(scope: :all)
|
348
419
|
# => "<MyObject[2](DEFAULT_FLAG / AO1_FLAG1 / AO2_FLAG1) !!I1 | VI2!! Default Info | Complex Info | Verbose Info :: Name>"
|
349
420
|
|
421
|
+
my_object.inspect! # 👀 Same as passing in `scope: :all`
|
422
|
+
# => "<MyObject[2](DEFAULT_FLAG / AO1_FLAG1 / AO2_FLAG1) !!I1 | VI2!! Default Info | Complex Info | Verbose Info :: Name>"
|
423
|
+
|
350
424
|
ObjectInspector.configuration.default_scope = :complex
|
351
|
-
my_object
|
352
|
-
|
425
|
+
my_object # =>
|
426
|
+
<MyObject[2](DEFAULT_FLAG / *) !!I1 | *!! Default Info | Complex Info | * :: Name>
|
353
427
|
|
354
428
|
ObjectInspector.configuration.default_scope = %i[self complex verbose]
|
355
|
-
my_object
|
356
|
-
|
429
|
+
my_object # =>
|
430
|
+
<MyObject[2](DEFAULT_FLAG / AO1_FLAG1 / AO2_FLAG1) !!I1 | VI2!! Default Info | Complex Info | Verbose Info :: Name>
|
357
431
|
|
358
432
|
ObjectInspector.configuration.default_scope = :all
|
359
|
-
my_object
|
360
|
-
|
433
|
+
my_object # =>
|
434
|
+
<MyObject[2](DEFAULT_FLAG / AO1_FLAG1 / AO2_FLAG1) !!I1 | VI2!! Default Info | Complex Info | Verbose Info :: Name>
|
361
435
|
```
|
362
436
|
|
363
437
|
## Wrapped Objects
|
@@ -366,7 +440,7 @@ If the Object being inspected wraps another object--i.e. defines #to_model and #
|
|
366
440
|
|
367
441
|
```ruby
|
368
442
|
class MyWrapperObject
|
369
|
-
include ObjectInspector::
|
443
|
+
include ObjectInspector::InspectBehaviors
|
370
444
|
|
371
445
|
def to_model
|
372
446
|
@to_model ||= MyWrappedObject.new
|
@@ -375,19 +449,24 @@ class MyWrapperObject
|
|
375
449
|
private
|
376
450
|
|
377
451
|
def inspect_flags = "WRAPPER_FLAG1"
|
452
|
+
def inspect_issues(scope:) = scope.complex? { "CI1" }
|
378
453
|
end
|
379
454
|
|
380
455
|
class MyWrappedObject
|
381
|
-
include ObjectInspector::
|
456
|
+
include ObjectInspector::InspectBehaviors
|
382
457
|
|
383
458
|
private
|
384
459
|
|
385
460
|
def inspect_flags = "FLAG1 / FLAG2"
|
386
461
|
def inspect_info = "INFO"
|
462
|
+
def inspect_issues(scope:) = scope.complex? { "CI1" }
|
387
463
|
end
|
388
464
|
|
389
|
-
MyWrapperObject.new
|
390
|
-
|
465
|
+
MyWrapperObject.new # =>
|
466
|
+
<MyWrapperObject(WRAPPER_FLAG1) !!*!!> ⇨ <MyWrappedObject(FLAG1 / FLAG2) !!*!! INFO>
|
467
|
+
|
468
|
+
MyWrapperObject.new! # =>
|
469
|
+
<MyWrapperObject(WRAPPER_FLAG1) !!CI1!!> ⇨ <MyWrappedObject(FLAG1 / FLAG2) !!CI1!! INFO>
|
391
470
|
```
|
392
471
|
|
393
472
|
This feature is recursive.
|
@@ -398,7 +477,7 @@ If the Object being inspected is wrapped by an object that delegates all unknown
|
|
398
477
|
|
399
478
|
```ruby
|
400
479
|
class MyDelegatingWrapperObject
|
401
|
-
include ObjectInspector::
|
480
|
+
include ObjectInspector::InspectBehaviors
|
402
481
|
|
403
482
|
def initialize(my_object)
|
404
483
|
@my_object = my_object
|
@@ -429,7 +508,7 @@ class MyDelegatingWrapperObject
|
|
429
508
|
end
|
430
509
|
|
431
510
|
class MyWrappedObject
|
432
|
-
include ObjectInspector::
|
511
|
+
include ObjectInspector::InspectBehaviors
|
433
512
|
|
434
513
|
def display_name
|
435
514
|
"WRAPPED_OBJECT_NAME"
|
@@ -443,8 +522,8 @@ class MyWrappedObject
|
|
443
522
|
def inspect_name = "NAME"
|
444
523
|
end
|
445
524
|
|
446
|
-
MyDelegatingWrapperObject.new(MyWrappedObject.new)
|
447
|
-
|
525
|
+
MyDelegatingWrapperObject.new(MyWrappedObject.new) # =>
|
526
|
+
<MyDelegatingWrapperObject> ⇨ <MyWrappedObject(FLAG1) !!ISSUE1!! INFO :: NAME>
|
448
527
|
```
|
449
528
|
|
450
529
|
## On-the-fly Inspect Methods
|
@@ -453,7 +532,7 @@ When passed as an option (as opposed to being called via an Object-defined metho
|
|
453
532
|
|
454
533
|
```ruby
|
455
534
|
class MyObject
|
456
|
-
include ObjectInspector::
|
535
|
+
include ObjectInspector::InspectBehaviors
|
457
536
|
|
458
537
|
def my_method1 = "Result1"
|
459
538
|
def my_method2 = "Result2"
|
@@ -461,9 +540,9 @@ class MyObject
|
|
461
540
|
def inspect_info = :my_method2
|
462
541
|
end
|
463
542
|
|
464
|
-
MyObject.new.inspect(info: "my_method1")
|
465
|
-
MyObject.new.inspect(info: :my_method2)
|
466
|
-
MyObject.new.inspect
|
543
|
+
MyObject.new.inspect(info: "my_method1") # => "<MyObject my_method1>"
|
544
|
+
MyObject.new.inspect(info: :my_method2) # => "<MyObject Result2>"
|
545
|
+
MyObject.new.inspect # => "<MyObject my_method2>"
|
467
546
|
```
|
468
547
|
|
469
548
|
## Clearing Output for Specified Inspect Method
|
@@ -472,7 +551,7 @@ Pass `nil` to any inspect method type to not display it:
|
|
472
551
|
|
473
552
|
```ruby
|
474
553
|
class MyObject
|
475
|
-
include ObjectInspector::
|
554
|
+
include ObjectInspector::InspectBehaviors
|
476
555
|
|
477
556
|
def inspect_identification = "My Object"
|
478
557
|
def inspect_info = "INFO"
|
@@ -501,7 +580,7 @@ class MyCustomFormatter < ObjectInspector::BaseFormatter
|
|
501
580
|
end
|
502
581
|
|
503
582
|
class MyObject
|
504
|
-
include ObjectInspector::
|
583
|
+
include ObjectInspector::InspectBehaviors
|
505
584
|
|
506
585
|
def inspect
|
507
586
|
super(
|
@@ -513,8 +592,8 @@ class MyObject
|
|
513
592
|
end
|
514
593
|
end
|
515
594
|
|
516
|
-
MyObject.new
|
517
|
-
|
595
|
+
MyObject.new # =>
|
596
|
+
[IDENTIFICATION Flags: FLAG1 / FLAG2 -- Info: INFO -- Name: NAME]
|
518
597
|
```
|
519
598
|
|
520
599
|
See examples:
|
@@ -522,13 +601,42 @@ See examples:
|
|
522
601
|
- [ObjectInspector::TemplatingFormatter]
|
523
602
|
- [ObjectInspector::CombiningFormatter]
|
524
603
|
|
604
|
+
## Help
|
605
|
+
|
606
|
+
### How can I see the original inspect output on ActiveRecord objects?
|
607
|
+
|
608
|
+
Simply [disable Object Inspector](#disabling-object-inspector) and you'll see ActiveRecord's Pretty Print formatting shine through again. For example:
|
609
|
+
|
610
|
+
```ruby
|
611
|
+
class User < ApplicationRecord
|
612
|
+
include ObjectInspectionBehaviors # 👀 Defined above.
|
613
|
+
|
614
|
+
# ...
|
615
|
+
end
|
616
|
+
|
617
|
+
User.new # =>
|
618
|
+
<User[1] :: John Smith>
|
619
|
+
|
620
|
+
ObjectInspector.configuration.disable; # =>
|
621
|
+
-> ObjectInspector disabled
|
622
|
+
|
623
|
+
User.new # =>
|
624
|
+
#<User:0x0000000125ce9890
|
625
|
+
id: "6c6d6f4b-05fd-4d81-af3e-1947a6a38aa0",
|
626
|
+
first_name: "John",
|
627
|
+
last_name: "Smith",
|
628
|
+
time_zone: nil,
|
629
|
+
created_at: "2025-02-10 12:27:23.793833000 -0600",
|
630
|
+
updated_at: "2025-02-11 13:15:00.301991000 -0600">
|
631
|
+
```
|
632
|
+
|
525
633
|
## Supporting Gems
|
526
634
|
|
527
635
|
Object Inspector works great with the [Object Identifier](https://github.com/pdobb/object_identifier) gem.
|
528
636
|
|
529
637
|
```ruby
|
530
638
|
class MyObject
|
531
|
-
include ObjectInspector::
|
639
|
+
include ObjectInspector::InspectBehaviors
|
532
640
|
|
533
641
|
def my_method1
|
534
642
|
1
|
@@ -550,8 +658,50 @@ class MyObject
|
|
550
658
|
def inspect_name = "NAME"
|
551
659
|
end
|
552
660
|
|
553
|
-
MyObject.new
|
554
|
-
|
661
|
+
MyObject.new # =>
|
662
|
+
<MyObject[my_method1:1, my_method2:2](FLAG1 / FLAG2) !!ISSUE1 | ISSUE2!! INFO :: NAME>
|
663
|
+
```
|
664
|
+
|
665
|
+
## Adding Utilities Methods to `.irbrc` / `.pryrc`
|
666
|
+
|
667
|
+
One may wish to add some convenience methods to their project-local `.irbrc`/`.pryrc` file, and/or their global `~/.irbrc`/`~/.pryrc` file. For example:
|
668
|
+
|
669
|
+
```ruby
|
670
|
+
# OBJECT INSPECTOR GEM
|
671
|
+
|
672
|
+
def toggle_object_inspector = ObjectInspector.configuration.toggle
|
673
|
+
alias oit toggle_object_inspector
|
674
|
+
|
675
|
+
def get_object_inspector_current_scope
|
676
|
+
ObjectInspector.configuration.default_scope
|
677
|
+
end
|
678
|
+
alias oi get_object_inspector_current_scope
|
679
|
+
|
680
|
+
# :simple is the default inspection scope.
|
681
|
+
def set_object_inspector_scope_simple = set_object_inspector_scope(:simple)
|
682
|
+
alias ois set_object_inspector_scope_simple
|
683
|
+
|
684
|
+
def set_object_inspector_scope_complex = set_object_inspector_scope(:complex)
|
685
|
+
alias oic set_object_inspector_scope_complex
|
686
|
+
|
687
|
+
def set_object_inspector_scope_verbose = set_object_inspector_scope(:verbose)
|
688
|
+
alias oiv set_object_inspector_scope_verbose
|
689
|
+
|
690
|
+
# Set :all (wild-card) inspection scope.
|
691
|
+
def set_object_inspector_scope_all = set_object_inspector_scope(:all)
|
692
|
+
alias oia set_object_inspector_scope_all
|
693
|
+
|
694
|
+
# Set a custom scope or set of scopes.
|
695
|
+
#
|
696
|
+
# @example
|
697
|
+
# set_object_inspector_scope(:my_custom_scope)
|
698
|
+
# set_object_inspector_scope(:complex, :verbose)
|
699
|
+
# set_object_inspector_scope(%i[complex verbose my_custom_scope])
|
700
|
+
def set_object_inspector_scope(*names)
|
701
|
+
ObjectInspector.configuration.default_scope = *names
|
702
|
+
get_object_inspector_current_scope
|
703
|
+
end
|
704
|
+
alias oiset set_object_inspector_scope
|
555
705
|
```
|
556
706
|
|
557
707
|
## Performance
|
@@ -590,13 +740,13 @@ load "script/benchmarking/formatters.rb"
|
|
590
740
|
#
|
591
741
|
# Comparison:
|
592
742
|
# ObjectInspector::TemplatingFormatter: 65856.3 i/s
|
593
|
-
# ObjectInspector::CombiningFormatter: 60920.0 i/s - 1.
|
743
|
+
# ObjectInspector::CombiningFormatter: 60920.0 i/s - 1.13x slower
|
594
744
|
# == Done
|
595
745
|
```
|
596
746
|
|
597
747
|
#### Benchmarking Custom Formatters
|
598
748
|
|
599
|
-
Custom Formatters may be similarly gauged for comparison by putting them into a constant `CUSTOM_FORMATTER_CLASSES` before
|
749
|
+
Custom Formatters may be similarly gauged for comparison by putting them into a constant `CUSTOM_FORMATTER_CLASSES` before loading the script in the IRB console for this gem.
|
600
750
|
|
601
751
|
```ruby
|
602
752
|
CUSTOM_FORMATTER_CLASSES = [MyCustomFormatter]
|
@@ -1,17 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
4
|
-
# ObjectInspector.
|
3
|
+
# Defines general conversion functions used by ObjectInspector.
|
5
4
|
module ObjectInspector::Conversions
|
6
5
|
module_function
|
7
6
|
|
7
|
+
# :reek:UncommunicativeMethodName
|
8
|
+
|
8
9
|
# Convert the passed in value to an {ObjectInspector::Scope} object.
|
9
10
|
# Just returns the passed in value if it already is an
|
10
11
|
# {ObjectInspector::Scope} object.
|
11
12
|
#
|
12
|
-
# @
|
13
|
+
# @example
|
14
|
+
# ObjectInspector::Conversions.Scope("test")
|
15
|
+
# # => <ObjectInspector::Scope :: ["test"]>
|
13
16
|
#
|
14
|
-
#
|
17
|
+
# ObjectInspector::Conversions.Scope(
|
18
|
+
# ObjectInspector::Scope.new(:my_custom_scope),
|
19
|
+
# )
|
20
|
+
# # => <ObjectInspector::Scope :: ["my_custom_scope"]>
|
21
|
+
#
|
22
|
+
# @return [ObjectInspector::Scope]
|
15
23
|
def Scope(value) # rubocop:disable Naming/MethodName
|
16
24
|
case value
|
17
25
|
when ObjectInspector::Scope
|
@@ -1,9 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# {#
|
6
|
-
# "inspect" String.
|
3
|
+
# An abstract base class that interfaces with {ObjectInspector::Inspector}
|
4
|
+
# objects to combine the supplied {#identification}, {#flags}, {#info}, and
|
5
|
+
# {#name} strings into a friendly "inspect" String.
|
7
6
|
class ObjectInspector::BaseFormatter
|
8
7
|
attr_reader :inspector
|
9
8
|
|
@@ -21,49 +20,49 @@ class ObjectInspector::BaseFormatter
|
|
21
20
|
|
22
21
|
# Delegates to {Inspector#wrapped_object_inspection_result}.
|
23
22
|
#
|
24
|
-
# @return [String]
|
25
|
-
# @return [NilClass]
|
23
|
+
# @return [String] If given.
|
24
|
+
# @return [NilClass] If not given.
|
26
25
|
def wrapped_object_inspection_result
|
27
26
|
@wrapped_object_inspection_result ||=
|
28
|
-
|
27
|
+
inspector.wrapped_object_inspection_result
|
29
28
|
end
|
30
29
|
|
31
30
|
# Delegates to {Inspector#identification}.
|
32
31
|
#
|
33
|
-
# @return [String]
|
32
|
+
# @return [String] If given.
|
34
33
|
def identification
|
35
|
-
@identification ||=
|
34
|
+
@identification ||= inspector.identification
|
36
35
|
end
|
37
36
|
|
38
37
|
# Delegates to {Inspector#flags}.
|
39
38
|
#
|
40
|
-
# @return [String]
|
41
|
-
# @return [NilClass]
|
39
|
+
# @return [String] If given.
|
40
|
+
# @return [NilClass] If not given.
|
42
41
|
def flags
|
43
|
-
@flags ||=
|
42
|
+
@flags ||= inspector.flags
|
44
43
|
end
|
45
44
|
|
46
45
|
# Delegates to {Inspector#issues}.
|
47
46
|
#
|
48
|
-
# @return [String]
|
49
|
-
# @return [NilClass]
|
47
|
+
# @return [String] If given.
|
48
|
+
# @return [NilClass] If not given.
|
50
49
|
def issues
|
51
|
-
@issues ||=
|
50
|
+
@issues ||= inspector.issues
|
52
51
|
end
|
53
52
|
|
54
53
|
# Delegates to {Inspector#info}.
|
55
54
|
#
|
56
|
-
# @return [String]
|
57
|
-
# @return [NilClass]
|
55
|
+
# @return [String] If given.
|
56
|
+
# @return [NilClass] If not given.
|
58
57
|
def info
|
59
|
-
@info ||=
|
58
|
+
@info ||= inspector.info
|
60
59
|
end
|
61
60
|
|
62
61
|
# Delegates to {Inspector#name}.
|
63
62
|
#
|
64
|
-
# @return [String]
|
65
|
-
# @return [NilClass]
|
63
|
+
# @return [String] If given.
|
64
|
+
# @return [NilClass] If not given.
|
66
65
|
def name
|
67
|
-
@name ||=
|
66
|
+
@name ||= inspector.name
|
68
67
|
end
|
69
68
|
end
|
@@ -1,8 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# ObjectInspector::
|
4
|
-
#
|
5
|
-
# output format by combining Strings.
|
3
|
+
# Specializes on {ObjectInspector::BaseFormatter} to return the standard/default
|
4
|
+
# inspect output format by combining Strings.
|
6
5
|
#
|
7
6
|
# @attr (see BaseFormatter)
|
8
7
|
class ObjectInspector::CombiningFormatter < ObjectInspector::BaseFormatter
|
@@ -4,9 +4,8 @@
|
|
4
4
|
# :reek:TooManyMethods
|
5
5
|
# rubocop:disable Metrics/ClassLength
|
6
6
|
|
7
|
-
# ObjectInspector::
|
8
|
-
#
|
9
|
-
# output format via String templates.
|
7
|
+
# Specializes on {ObjectInspector::BaseFormatter} to return the standard/default
|
8
|
+
# inspect output format using String templates.
|
10
9
|
#
|
11
10
|
# @attr (see BaseFormatter)
|
12
11
|
class ObjectInspector::TemplatingFormatter < ObjectInspector::BaseFormatter
|
@@ -52,8 +51,7 @@ class ObjectInspector::TemplatingFormatter < ObjectInspector::BaseFormatter
|
|
52
51
|
"#{wrapped_object_inspection_result}"
|
53
52
|
end
|
54
53
|
|
55
|
-
# rubocop:disable Metrics/MethodLength
|
56
|
-
def build_string
|
54
|
+
def build_string # rubocop:disable Metrics/MethodLength
|
57
55
|
if flags
|
58
56
|
build_string_with_flags_and_maybe_issues_and_info_and_name
|
59
57
|
elsif issues
|
@@ -66,7 +64,6 @@ class ObjectInspector::TemplatingFormatter < ObjectInspector::BaseFormatter
|
|
66
64
|
build_base_string
|
67
65
|
end
|
68
66
|
end
|
69
|
-
# rubocop:enable Metrics/MethodLength
|
70
67
|
|
71
68
|
def build_string_with_flags_and_maybe_issues_and_info_and_name
|
72
69
|
if issues
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# ObjectInspector::InspectBehaviors can be included into any object to override
|
4
|
+
# the default `#inspect` method for that object to instead call
|
5
|
+
# {ObjectInspector::Inspector.inspect}.
|
6
|
+
module ObjectInspector::InspectBehaviors
|
7
|
+
# Calls {ObjectInspector::Inspector.inspect} on the passed in `object`,
|
8
|
+
# passing through any keyword arguments.
|
9
|
+
#
|
10
|
+
# @return [String]
|
11
|
+
def inspect(**)
|
12
|
+
return super() if ObjectInspector.configuration.disabled?
|
13
|
+
|
14
|
+
ObjectInspector::Inspector.inspect(self, **)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Like {#inspect} but forces scope to `:all`. This (the bang (!) version) is
|
18
|
+
# considered the "more dangerous" version of {#inspect} in the sense that the
|
19
|
+
# `:all` scope may result in additional queries or extra processing--depending
|
20
|
+
# on how the inspect hooks are setup.
|
21
|
+
#
|
22
|
+
# @return [String]
|
23
|
+
def inspect!(**)
|
24
|
+
ObjectInspector::Inspector.inspect(self, **, scope: :all)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# :reek:UtilityFunction
|
30
|
+
|
31
|
+
# Allow ActiveRecord::Core#pretty_print to produce the standard Pretty-printed
|
32
|
+
# output (vs just straight #inspect String) when ObjectInspector is disabled.
|
33
|
+
def custom_inspect_method_defined?
|
34
|
+
ObjectInspector.configuration.enabled?
|
35
|
+
end
|
36
|
+
end
|
@@ -1,10 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# ObjectInspector::Inspector organizes inspection of the associated {#object}
|
4
|
-
# via the passed in options and via an {ObjectInspector::BaseFormatter}
|
5
|
-
# instance.
|
6
|
-
#
|
7
3
|
# :reek:TooManyMethods
|
4
|
+
|
5
|
+
# Organizes inspection of the associated {#object} via the passed in options and
|
6
|
+
# via an {ObjectInspector::BaseFormatter} instance.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# ObjectInspector::Inspector.inspect(
|
10
|
+
# self,
|
11
|
+
# identification: self.class.name,
|
12
|
+
# flags: "FLAG1",
|
13
|
+
# issues: "ISSUE1",
|
14
|
+
# info: "INFO",
|
15
|
+
# name: "NAME",
|
16
|
+
# )
|
17
|
+
# # => "<Object(FLAG1) !!ISSUE1!! INFO :: NAME>"
|
8
18
|
class ObjectInspector::Inspector
|
9
19
|
attr_reader :object
|
10
20
|
|
@@ -12,9 +22,9 @@ class ObjectInspector::Inspector
|
|
12
22
|
# required to use ObjectInspector::Inspector.
|
13
23
|
#
|
14
24
|
# @return [String]
|
15
|
-
def self.inspect(...)
|
16
|
-
|
17
|
-
|
25
|
+
def self.inspect(...) = new(...).to_s
|
26
|
+
|
27
|
+
# :reek:DuplicateMethodCall (ObjectInspecto.configuration)
|
18
28
|
|
19
29
|
# @param object [Object] the object being inspected
|
20
30
|
# @param scope [Symbol] Object inspection type. For example:
|
@@ -22,18 +32,17 @@ class ObjectInspector::Inspector
|
|
22
32
|
# <custom> -- Anything else that makes sense for {#object} to key
|
23
33
|
# on
|
24
34
|
# @param formatter [ObjectInspector::BaseFormatter]
|
25
|
-
# (ObjectInspector.configuration.formatter)
|
26
|
-
# to use for formatting the inspect String
|
27
|
-
# @param kwargs [Hash]
|
28
|
-
# {ObjectInspector::
|
29
|
-
# methods
|
30
|
-
#
|
31
|
-
# :reek:DuplicateMethodCall (ObjectInspecto.configuration)
|
35
|
+
# (ObjectInspector.configuration.formatter) The formatter object type
|
36
|
+
# to use for formatting the inspect String.
|
37
|
+
# @param kwargs [Hash] Options to be sent to {#object} via
|
38
|
+
# {ObjectInspector::InterrogateObject} when calling the `inspect_*`
|
39
|
+
# methods.
|
32
40
|
def initialize(
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
41
|
+
object,
|
42
|
+
scope: ObjectInspector.configuration.default_scope,
|
43
|
+
formatter: ObjectInspector.configuration.formatter_class,
|
44
|
+
**kwargs
|
45
|
+
)
|
37
46
|
@object = object
|
38
47
|
@scope = ObjectInspector::Conversions.Scope(scope)
|
39
48
|
@formatter_class = formatter
|
@@ -47,10 +56,11 @@ class ObjectInspector::Inspector
|
|
47
56
|
formatter.call
|
48
57
|
end
|
49
58
|
|
50
|
-
# Generate the inspect String for the wrapped object, if
|
59
|
+
# Generate the inspect String for the wrapped object, if `self` is a wrapper
|
60
|
+
# object.
|
51
61
|
#
|
52
|
-
# @return [String]
|
53
|
-
# @return [NilClass]
|
62
|
+
# @return [String] If {#object_is_a_wrapper?}.
|
63
|
+
# @return [NilClass] If not {#object_is_a_wrapper?}.
|
54
64
|
def wrapped_object_inspection_result
|
55
65
|
return unless object_is_a_wrapper?
|
56
66
|
|
@@ -58,7 +68,8 @@ class ObjectInspector::Inspector
|
|
58
68
|
extract_wrapped_object,
|
59
69
|
scope: @scope,
|
60
70
|
formatter: @formatter_class,
|
61
|
-
kwargs: @kwargs
|
71
|
+
kwargs: @kwargs,
|
72
|
+
)
|
62
73
|
end
|
63
74
|
|
64
75
|
# Core object identification details, such as the {#object} class name and
|
@@ -66,62 +77,68 @@ class ObjectInspector::Inspector
|
|
66
77
|
#
|
67
78
|
# @return [String]
|
68
79
|
def identification
|
69
|
-
(value(key: :identification) ||
|
80
|
+
(value(key: :identification) || object.class).to_s
|
70
81
|
end
|
71
82
|
|
72
83
|
# Boolean flags/states applicable to {#object}.
|
73
84
|
#
|
74
|
-
# @return [String]
|
75
|
-
# @return [NilClass]
|
85
|
+
# @return [String] If given.
|
86
|
+
# @return [NilClass] If not given.
|
76
87
|
def flags
|
77
88
|
value(key: :flags)
|
78
89
|
end
|
79
90
|
|
80
91
|
# Issues/Warnings applicable to {#object}.
|
81
92
|
#
|
82
|
-
# @return [String]
|
83
|
-
# @return [NilClass]
|
93
|
+
# @return [String] If given.
|
94
|
+
# @return [NilClass] If not given.
|
84
95
|
def issues
|
85
96
|
value(key: :issues)
|
86
97
|
end
|
87
98
|
|
88
99
|
# Informational details applicable to {#object}.
|
89
100
|
#
|
90
|
-
# @return [String]
|
91
|
-
# @return [NilClass]
|
101
|
+
# @return [String] If given.
|
102
|
+
# @return [NilClass] If not given.
|
92
103
|
def info
|
93
104
|
value(key: :info)
|
94
105
|
end
|
95
106
|
|
96
107
|
# A human-friendly identifier for {#object}.
|
97
108
|
#
|
98
|
-
# @return [String]
|
99
|
-
# @return [NilClass]
|
109
|
+
# @return [String] If given.
|
110
|
+
# @return [NilClass] If not given.
|
100
111
|
def name
|
101
112
|
key = :name
|
102
113
|
|
103
114
|
if @kwargs.key?(key)
|
104
|
-
value(key:
|
115
|
+
value(key:)
|
105
116
|
else
|
106
117
|
interrogate_object_inspect_method(key) ||
|
107
118
|
interrogate_object(
|
108
|
-
method_name: :display_name,
|
119
|
+
method_name: :display_name,
|
120
|
+
kwargs: object_method_keyword_arguments,
|
121
|
+
)
|
109
122
|
end
|
110
123
|
end
|
111
124
|
|
112
125
|
private
|
113
126
|
|
127
|
+
attr_reader :scope,
|
128
|
+
:formatter_class,
|
129
|
+
:kwargs
|
130
|
+
|
114
131
|
def formatter
|
115
|
-
|
132
|
+
formatter_class.new(self)
|
116
133
|
end
|
117
134
|
|
118
|
-
# @return [String]
|
119
|
-
# `#{object_inspection_method_name}` (e.g. `inspect_flags`)
|
120
|
-
# @return [NilClass]
|
135
|
+
# @return [String] If `key` is found in {#kwargs} or if {#object} responds to
|
136
|
+
# `#{object_inspection_method_name}` (e.g. `inspect_flags`).
|
137
|
+
# @return [NilClass] If not found in {#kwargs} or {#object}.
|
121
138
|
def value(key:)
|
122
139
|
return_value =
|
123
|
-
if
|
124
|
-
evaluate_passed_in_value(
|
140
|
+
if kwargs.key?(key)
|
141
|
+
evaluate_passed_in_value(kwargs[key])
|
125
142
|
else
|
126
143
|
interrogate_object_inspect_method(key)
|
127
144
|
end
|
@@ -132,10 +149,10 @@ class ObjectInspector::Inspector
|
|
132
149
|
# Call `value` on {#object} if it responds to it and the result is not nil,
|
133
150
|
# else just return `value`.
|
134
151
|
#
|
135
|
-
# @return [#to_s]
|
136
|
-
# isn't nil
|
137
|
-
# @return [#nil]
|
138
|
-
# result is nil
|
152
|
+
# @return [#to_s] If {#object} responds to `value` and if the call result
|
153
|
+
# isn't nil.
|
154
|
+
# @return [#nil] If {#object} doesn't respond to `value` or if the call
|
155
|
+
# result is nil.
|
139
156
|
def evaluate_passed_in_value(value)
|
140
157
|
if value.is_a?(Symbol)
|
141
158
|
interrogate_object(method_name: value) || value
|
@@ -146,47 +163,44 @@ class ObjectInspector::Inspector
|
|
146
163
|
|
147
164
|
# Attempt to call `inspect_*` on {#object} based on the passed in `name`.
|
148
165
|
#
|
149
|
-
# @return [String]
|
150
|
-
# `#{object_inspection_method_name}` (e.g. `inspect_flags`)
|
151
|
-
# @return [NilClass]
|
166
|
+
# @return [String] If {#object} responds to
|
167
|
+
# `#{object_inspection_method_name}` (e.g. `inspect_flags`).
|
168
|
+
# @return [NilClass] If not found on {#object}.
|
152
169
|
def interrogate_object_inspect_method(
|
153
|
-
|
154
|
-
|
170
|
+
name,
|
171
|
+
prefix: ObjectInspector.configuration.inspect_method_prefix
|
172
|
+
)
|
155
173
|
interrogate_object(
|
156
|
-
method_name: object_inspection_method_name(name, prefix:
|
157
|
-
kwargs: object_method_keyword_arguments
|
174
|
+
method_name: object_inspection_method_name(name, prefix:),
|
175
|
+
kwargs: object_method_keyword_arguments,
|
176
|
+
)
|
158
177
|
end
|
159
178
|
|
160
179
|
def interrogate_object(method_name:, kwargs: {})
|
161
|
-
|
162
|
-
ObjectInspector::ObjectInterrogator.new(
|
163
|
-
object: @object,
|
164
|
-
method_name: method_name,
|
165
|
-
kwargs: kwargs)
|
166
|
-
|
167
|
-
interrogator.call
|
180
|
+
ObjectInspector::InterrogateObject.(object, method_name:, kwargs:)
|
168
181
|
end
|
169
182
|
|
170
183
|
# :reek:UtilityFunction
|
184
|
+
|
171
185
|
def object_inspection_method_name(
|
172
|
-
|
173
|
-
|
186
|
+
name,
|
187
|
+
prefix: ObjectInspector.configuration.inspect_method_prefix
|
188
|
+
)
|
174
189
|
"#{prefix}_#{name}"
|
175
190
|
end
|
176
191
|
|
177
192
|
def object_method_keyword_arguments
|
178
|
-
{
|
179
|
-
scope: @scope,
|
180
|
-
}
|
193
|
+
{ scope: }
|
181
194
|
end
|
182
195
|
|
183
196
|
def extract_wrapped_object
|
184
|
-
|
197
|
+
object.to_model
|
185
198
|
end
|
186
199
|
|
187
200
|
# :reek:ManualDispatch
|
201
|
+
|
188
202
|
def object_is_a_wrapper?
|
189
|
-
|
190
|
-
|
203
|
+
object.respond_to?(:to_model) &&
|
204
|
+
object.to_model != object
|
191
205
|
end
|
192
206
|
end
|
@@ -1,25 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
4
|
-
#
|
3
|
+
# Collaborates with {#object} to return {#object}#{#method_name} if {#object}
|
4
|
+
# responds to {#method_name}.
|
5
5
|
#
|
6
|
-
# If
|
6
|
+
# If {#object}#{#method_name} accepts the supplied `kwargs` then they are passed
|
7
7
|
# in as well. If not, then any supplied `kwargs` will be ignored.
|
8
|
-
class ObjectInspector::
|
8
|
+
class ObjectInspector::InterrogateObject
|
9
|
+
def self.call(...) = new(...).call
|
10
|
+
|
9
11
|
attr_reader :object,
|
10
12
|
:method_name,
|
11
13
|
:kwargs
|
12
14
|
|
13
|
-
def initialize(object
|
15
|
+
def initialize(object, method_name:, kwargs: {})
|
14
16
|
@object = object
|
15
17
|
@method_name = method_name
|
16
18
|
@kwargs = kwargs
|
17
19
|
end
|
18
20
|
|
19
|
-
# @return [String, ...]
|
21
|
+
# @return [String, ...] Whatever type Object#{#method_name} returns.
|
20
22
|
#
|
21
|
-
# @raise [ArgumentError]
|
22
|
-
# signature
|
23
|
+
# @raise [ArgumentError] If Object#{#method_name} has an unexpected method
|
24
|
+
# signature.
|
23
25
|
def call
|
24
26
|
return unless object_responds_to_method_name?
|
25
27
|
|
@@ -40,6 +42,7 @@ class ObjectInspector::ObjectInterrogator
|
|
40
42
|
|
41
43
|
# :reek:ManualDispatch
|
42
44
|
# :reek:BooleanParameter
|
45
|
+
|
43
46
|
def object_responds_to_method_name?(include_private: true)
|
44
47
|
object.respond_to?(method_name, include_private)
|
45
48
|
end
|
@@ -2,9 +2,8 @@
|
|
2
2
|
|
3
3
|
# :reek:TooManyMethods
|
4
4
|
|
5
|
-
#
|
6
|
-
#
|
7
|
-
# "scope" within objects.
|
5
|
+
# Defines a predicate method that matches {#names} and responds with `true`.
|
6
|
+
# This is a prettier way to test for a given type of "scope" within objects.
|
8
7
|
#
|
9
8
|
# It is possible to pass in multiple scope names to match on.
|
10
9
|
#
|
@@ -13,6 +12,16 @@
|
|
13
12
|
# Passing a block to a scope predicate falls back to the out-of-scope
|
14
13
|
# placeholder (`*` by default) if the scope does not match.
|
15
14
|
#
|
15
|
+
# @example
|
16
|
+
# ObjectInspector::Scope.new
|
17
|
+
# # => <ObjectInspector::Scope :: ["self"]>
|
18
|
+
#
|
19
|
+
# ObjectInspector::Scope.new(:my_custom_scope)
|
20
|
+
# # => <ObjectInspector::Scope :: ["my_custom_scope"]>
|
21
|
+
#
|
22
|
+
# ObjectInspector::Scope.new(%w[verbose complex])
|
23
|
+
# # => <ObjectInspector::Scope :: ["complex", "verbose"]>
|
24
|
+
#
|
16
25
|
# @see ActiveSupport::StringInquirer
|
17
26
|
# http://api.rubyonrails.org/classes/ActiveSupport/StringInquirer.html
|
18
27
|
#
|
@@ -20,8 +29,11 @@
|
|
20
29
|
class ObjectInspector::Scope
|
21
30
|
attr_reader :names
|
22
31
|
|
23
|
-
|
24
|
-
|
32
|
+
# :reek:FeatureEnvy
|
33
|
+
|
34
|
+
def initialize(*names)
|
35
|
+
names = names.empty? ? %w[self] : names.flatten
|
36
|
+
@names = names.map! { |name| String(name) }.sort!
|
25
37
|
end
|
26
38
|
|
27
39
|
# Join the passed in name parts with the passed in separator.
|
@@ -29,7 +41,9 @@ class ObjectInspector::Scope
|
|
29
41
|
# @param parts [Array<#to_s>]
|
30
42
|
# @param separator [#to_s] (ObjectInspector.configuration.flags_separator)
|
31
43
|
def join_name(
|
32
|
-
|
44
|
+
parts,
|
45
|
+
separator: ObjectInspector.configuration.name_separator
|
46
|
+
)
|
33
47
|
_join(parts, separator)
|
34
48
|
end
|
35
49
|
|
@@ -38,7 +52,9 @@ class ObjectInspector::Scope
|
|
38
52
|
# @param flags [Array<#to_s>]
|
39
53
|
# @param separator [#to_s] (ObjectInspector.configuration.flags_separator)
|
40
54
|
def join_flags(
|
41
|
-
|
55
|
+
flags,
|
56
|
+
separator: ObjectInspector.configuration.flags_separator
|
57
|
+
)
|
42
58
|
_join(flags, separator)
|
43
59
|
end
|
44
60
|
|
@@ -47,7 +63,9 @@ class ObjectInspector::Scope
|
|
47
63
|
# @param issues [Array<#to_s>]
|
48
64
|
# @param separator [#to_s] (ObjectInspector.configuration.issues_separator)
|
49
65
|
def join_issues(
|
50
|
-
|
66
|
+
issues,
|
67
|
+
separator: ObjectInspector.configuration.issues_separator
|
68
|
+
)
|
51
69
|
_join(issues, separator)
|
52
70
|
end
|
53
71
|
|
@@ -56,19 +74,21 @@ class ObjectInspector::Scope
|
|
56
74
|
# @param items [Array<#to_s>]
|
57
75
|
# @param separator [#to_s] (ObjectInspector.configuration.info_separator)
|
58
76
|
def join_info(
|
59
|
-
|
77
|
+
items,
|
78
|
+
separator: ObjectInspector.configuration.info_separator
|
79
|
+
)
|
60
80
|
_join(items, separator)
|
61
81
|
end
|
62
82
|
|
63
83
|
# Compare self with the passed in object.
|
64
84
|
#
|
65
|
-
# @return [TrueClass]
|
66
|
-
# @return [FalseClass]
|
67
|
-
# objects
|
85
|
+
# @return [TrueClass] If self and `other` resolve to the same set of objects.
|
86
|
+
# @return [FalseClass] If self and `other` resolve to a different set of
|
87
|
+
# objects.
|
68
88
|
def ==(other)
|
69
|
-
|
89
|
+
names == Array(other).map(&:to_s).sort!
|
70
90
|
end
|
71
|
-
|
91
|
+
alias eql? ==
|
72
92
|
|
73
93
|
# @return [String] the contents of {#names}, joined by `, `.
|
74
94
|
def to_s(separator: ", ")
|
@@ -80,6 +100,10 @@ class ObjectInspector::Scope
|
|
80
100
|
names
|
81
101
|
end
|
82
102
|
|
103
|
+
def inspect
|
104
|
+
"<#{self.class.name} :: #{names.inspect}>"
|
105
|
+
end
|
106
|
+
|
83
107
|
private
|
84
108
|
|
85
109
|
def method_missing(method_name, *args, &)
|
@@ -131,10 +155,11 @@ class ObjectInspector::Scope
|
|
131
155
|
end
|
132
156
|
|
133
157
|
def any_names_match?(other_name)
|
134
|
-
|
158
|
+
names.any?(other_name)
|
135
159
|
end
|
136
160
|
|
137
161
|
# :reek:BooleanParameter
|
162
|
+
|
138
163
|
def respond_to_missing?(method_name, include_private = false)
|
139
164
|
method_name[-1] == "?" || super
|
140
165
|
end
|
data/lib/object_inspector.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
3
|
+
# Defines the base namespace for all modules/classes used by the
|
4
4
|
# object_inspector gem.
|
5
5
|
module ObjectInspector
|
6
6
|
# Accessor for the {ObjectInspector::Configuration} object.
|
@@ -19,11 +19,11 @@ module ObjectInspector
|
|
19
19
|
@configuration = Configuration.new
|
20
20
|
end
|
21
21
|
|
22
|
+
# :reek:TooManyInstanceVariables
|
23
|
+
|
22
24
|
# ObjectInspector::Configuration stores the default configuration options for
|
23
25
|
# the ObjectInspector gem. Modification of attributes is possible at any time,
|
24
26
|
# and values will persist for the duration of the running process.
|
25
|
-
#
|
26
|
-
# :reek:TooManyInstanceVariables
|
27
27
|
class Configuration
|
28
28
|
attr_reader :formatter_class,
|
29
29
|
:inspect_method_prefix,
|
@@ -36,7 +36,8 @@ module ObjectInspector
|
|
36
36
|
:issues_separator,
|
37
37
|
:info_separator
|
38
38
|
|
39
|
-
def initialize
|
39
|
+
def initialize # rubocop:disable Metrics/MethodLength
|
40
|
+
@enabled = true
|
40
41
|
@formatter_class = TemplatingFormatter
|
41
42
|
@inspect_method_prefix = "inspect"
|
42
43
|
@default_scope = Scope.new(:self)
|
@@ -49,6 +50,21 @@ module ObjectInspector
|
|
49
50
|
@info_separator = " | "
|
50
51
|
end
|
51
52
|
|
53
|
+
def toggle = enabled? ? disable : enable
|
54
|
+
def enabled? = @enabled
|
55
|
+
|
56
|
+
def enable
|
57
|
+
@enabled = true
|
58
|
+
puts(" -> ObjectInspector enabled")
|
59
|
+
end
|
60
|
+
|
61
|
+
def disabled? = !enabled?
|
62
|
+
|
63
|
+
def disable
|
64
|
+
@enabled = false
|
65
|
+
puts(" -> ObjectInspector disabled")
|
66
|
+
end
|
67
|
+
|
52
68
|
def formatter_class=(value)
|
53
69
|
unless value.is_a?(Class)
|
54
70
|
raise(TypeError, "Formatter must be a Class constant")
|
@@ -99,8 +115,8 @@ require "object_inspector/version"
|
|
99
115
|
require "object_inspector/conversions"
|
100
116
|
require "object_inspector/inspector"
|
101
117
|
require "object_inspector/scope"
|
102
|
-
require "object_inspector/
|
103
|
-
require "object_inspector/
|
118
|
+
require "object_inspector/inspect_behaviors"
|
119
|
+
require "object_inspector/interrogate_object"
|
104
120
|
require "object_inspector/formatters/base_formatter"
|
105
121
|
require "object_inspector/formatters/combining_formatter"
|
106
122
|
require "object_inspector/formatters/templating_formatter"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: object_inspector
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul DobbinSchmaltz
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: benchmark-ips
|
@@ -82,9 +82,9 @@ files:
|
|
82
82
|
- lib/object_inspector/formatters/base_formatter.rb
|
83
83
|
- lib/object_inspector/formatters/combining_formatter.rb
|
84
84
|
- lib/object_inspector/formatters/templating_formatter.rb
|
85
|
+
- lib/object_inspector/inspect_behaviors.rb
|
85
86
|
- lib/object_inspector/inspector.rb
|
86
|
-
- lib/object_inspector/
|
87
|
-
- lib/object_inspector/object_interrogator.rb
|
87
|
+
- lib/object_inspector/interrogate_object.rb
|
88
88
|
- lib/object_inspector/scope.rb
|
89
89
|
- lib/object_inspector/version.rb
|
90
90
|
homepage: https://github.com/pdobb/object_inspector
|
@@ -110,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: '0'
|
112
112
|
requirements: []
|
113
|
-
rubygems_version: 3.
|
113
|
+
rubygems_version: 3.7.2
|
114
114
|
specification_version: 4
|
115
115
|
summary: Object Inspector builds uniformly formatted inspect output with customizable
|
116
116
|
amounts of detail.
|
@@ -1,14 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# ObjectInspector::InspectorsHelper can be included into any object to
|
4
|
-
# simplify the process of instantiating an ObjectInspector::Inspector and
|
5
|
-
# generating the inspection output.
|
6
|
-
module ObjectInspector::InspectorsHelper
|
7
|
-
# Calls {ObjectInspector::Inspector.inspect} on the passed in `object`,
|
8
|
-
# passing it the passed in `kwargs` (keyword arguments).
|
9
|
-
#
|
10
|
-
# @return [String]
|
11
|
-
def inspect(object = self, **)
|
12
|
-
ObjectInspector::Inspector.inspect(object, **)
|
13
|
-
end
|
14
|
-
end
|