object_inspector 0.1.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 +7 -0
- data/.gitignore +11 -0
- data/.travis.yml +19 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +42 -0
- data/LICENSE.txt +21 -0
- data/README.md +319 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/object_inspector/base_formatter.rb +85 -0
- data/lib/object_inspector/default_formatter.rb +33 -0
- data/lib/object_inspector/inspector.rb +126 -0
- data/lib/object_inspector/inspectors_helper.rb +14 -0
- data/lib/object_inspector/object_interrogator.rb +36 -0
- data/lib/object_inspector/version.rb +3 -0
- data/lib/object_inspector.rb +11 -0
- data/object_inspector.gemspec +40 -0
- metadata +163 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 695389e5c3a953c4bfd33d5fbe987008beb63c5a1235c4a8d3fdeb894b5727e5
|
4
|
+
data.tar.gz: a05becc6eec712e462d979fd6c23e4c6375cfb4bd2b9503e1752bd218bdf70ca
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0c6023ee714bcdebbb198d7d3a1635d4c696f262a7112b7f457821c03fc889bb75c68f0112a94c95c5c8ae253c0c07ef8f920b8e0708bc809274c3d4f63d10ae
|
7
|
+
data.tar.gz: f9d07b12b361f774800f47805c357373b3e674c61cf74299f8672d4237bb953fa12e6e7238840df5f2afede96dbb7fad09d69b4115e760929b73613aa463fe91
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
env:
|
2
|
+
global:
|
3
|
+
- CC_TEST_REPORTER_ID=7711465d4611bd7f1211f3262ac4ba750ffcda0574c3c6e4a6ba55446871dd17
|
4
|
+
sudo: false
|
5
|
+
language: ruby
|
6
|
+
rvm:
|
7
|
+
- 2.2.10
|
8
|
+
- 2.3.7
|
9
|
+
- 2.4.4
|
10
|
+
- 2.5.1
|
11
|
+
- ruby-head
|
12
|
+
before_install: gem install bundler -v 1.16.1
|
13
|
+
cache: bundler
|
14
|
+
before_script:
|
15
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
16
|
+
- chmod +x ./cc-test-reporter
|
17
|
+
- ./cc-test-reporter before-build
|
18
|
+
after_script:
|
19
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
object_inspector (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
byebug (10.0.2)
|
10
|
+
coderay (1.1.2)
|
11
|
+
docile (1.3.0)
|
12
|
+
json (2.1.0)
|
13
|
+
method_source (0.9.0)
|
14
|
+
minitest (5.11.3)
|
15
|
+
pry (0.11.3)
|
16
|
+
coderay (~> 1.1.0)
|
17
|
+
method_source (~> 0.9.0)
|
18
|
+
pry-byebug (3.6.0)
|
19
|
+
byebug (~> 10.0)
|
20
|
+
pry (~> 0.10)
|
21
|
+
rake (10.4.2)
|
22
|
+
simplecov (0.16.1)
|
23
|
+
docile (~> 1.1)
|
24
|
+
json (>= 1.8, < 3)
|
25
|
+
simplecov-html (~> 0.10.0)
|
26
|
+
simplecov-html (0.10.2)
|
27
|
+
|
28
|
+
PLATFORMS
|
29
|
+
ruby
|
30
|
+
|
31
|
+
DEPENDENCIES
|
32
|
+
bundler (~> 1.16)
|
33
|
+
byebug (~> 10.0)
|
34
|
+
minitest (~> 5.0)
|
35
|
+
object_inspector!
|
36
|
+
pry (~> 0.11)
|
37
|
+
pry-byebug (~> 3.6)
|
38
|
+
rake (~> 10.0)
|
39
|
+
simplecov (~> 0.16)
|
40
|
+
|
41
|
+
BUNDLED WITH
|
42
|
+
1.16.1
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 Paul Dobbins
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,319 @@
|
|
1
|
+
# ObjectInspector
|
2
|
+
|
3
|
+
[](http://badge.fury.io/rb/object_inspector)
|
4
|
+
[](https://travis-ci.org/objects-on-rails/display-case)
|
5
|
+
[](https://codeclimate.com/github/pdobb/object_inspector/test_coverage)
|
6
|
+
[](https://codeclimate.com/github/pdobb/object_inspector/maintainability)
|
7
|
+
|
8
|
+
ObjectInspector takes Object#inspect to the next level. Specify any combination of identification attributes, flags, info, and/or a name along with a self-definable scope option to represent an object in the console, in logging, or otherwise.
|
9
|
+
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem "object_inspector"
|
17
|
+
```
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install object_inspector
|
26
|
+
|
27
|
+
|
28
|
+
## Compatibility
|
29
|
+
|
30
|
+
Tested MRI Ruby Versions:
|
31
|
+
* 2.2.10
|
32
|
+
* 2.3.7
|
33
|
+
* 2.4.4
|
34
|
+
* 2.5.1
|
35
|
+
|
36
|
+
|
37
|
+
## Usage
|
38
|
+
|
39
|
+
Given, an object of any type, call ObjectInspector::Inspect#to_s.
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
class MyObject
|
43
|
+
def inspect
|
44
|
+
ObjectInspector::Inspector.new(self).to_s
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
MyObject.new.inspect # => "<MyObject>"
|
49
|
+
```
|
50
|
+
|
51
|
+
Or, just use the ObjectInspector::Inspector.inspect method.
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
class MyObject
|
55
|
+
def inspect
|
56
|
+
ObjectInspector::Inspector.inspect(self)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
MyObject.new.inspect # => "<MyObject>"
|
61
|
+
```
|
62
|
+
|
63
|
+
See also [Helper Usage](#helper-usage) for an even simpler usage option.
|
64
|
+
|
65
|
+
|
66
|
+
### Output Customization
|
67
|
+
|
68
|
+
Use ObjectInspector::Inspector#initialize options -- `identification`, `flags`, `info`, and `name` -- to customize inspect output.
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
class MyObject
|
72
|
+
def inspect
|
73
|
+
ObjectInspector::Inspector.inspect(
|
74
|
+
self,
|
75
|
+
identification: "My Object",
|
76
|
+
flags: "FLAG1",
|
77
|
+
info: "INFO",
|
78
|
+
name: "NAME")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
MyObject.new.inspect # => "<My Object[FLAG1] (INFO) :: NAME>"
|
83
|
+
```
|
84
|
+
|
85
|
+
Or, define `inspect_identification`, `inspect_flags`, `inspect_info`, and `inspect_name` in Object.
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
class MyObject
|
89
|
+
def inspect
|
90
|
+
ObjectInspector::Inspector.inspect(self)
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def inspect_identification
|
96
|
+
"My Object"
|
97
|
+
end
|
98
|
+
|
99
|
+
def inspect_flags
|
100
|
+
"FLAG1"
|
101
|
+
end
|
102
|
+
|
103
|
+
def inspect_info
|
104
|
+
"INFO"
|
105
|
+
end
|
106
|
+
|
107
|
+
def inspect_name
|
108
|
+
"NAME"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
MyObject.new.inspect # => "<My Object[FLAG1] (INFO) :: NAME>"
|
113
|
+
```
|
114
|
+
|
115
|
+
|
116
|
+
## Helper Usage
|
117
|
+
|
118
|
+
To save a little typing, include ObjectInspector::InspectHelper into an object and ObjectInspector::Inspector#to_s will be called for you on `self`.
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
class MyObject
|
122
|
+
include ObjectInspector::InspectorsHelper
|
123
|
+
end
|
124
|
+
|
125
|
+
MyObject.new.inspect # => "<MyObject>"
|
126
|
+
```
|
127
|
+
|
128
|
+
To access the ObjectInspector::Inspector's options via the helper, call into `super`.
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
class MyObject
|
132
|
+
include ObjectInspector::InspectorsHelper
|
133
|
+
|
134
|
+
def inspect
|
135
|
+
super(identification: "My Object",
|
136
|
+
flags: "FLAG1",
|
137
|
+
info: "INFO",
|
138
|
+
name: "NAME")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
MyObject.new.inspect # => "<My Object[FLAG1] (INFO) :: NAME>"
|
143
|
+
```
|
144
|
+
|
145
|
+
Or, define `inspect_identification`, `inspect_flags`, `inspect_info`, and `inspect_name` in Object.
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
class MyObject
|
149
|
+
include ObjectInspector::InspectorsHelper
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
def inspect_identification
|
154
|
+
"My Object"
|
155
|
+
end
|
156
|
+
|
157
|
+
def inspect_flags
|
158
|
+
"FLAG1"
|
159
|
+
end
|
160
|
+
|
161
|
+
def inspect_info
|
162
|
+
"INFO"
|
163
|
+
end
|
164
|
+
|
165
|
+
def inspect_name
|
166
|
+
"NAME"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
MyObject.new.inspect # => "<My Object[FLAG1] (INFO) :: NAME>"
|
171
|
+
```
|
172
|
+
|
173
|
+
|
174
|
+
#### Scope
|
175
|
+
|
176
|
+
Use the `scope` option to define the scope of the `inspect_` methods.
|
177
|
+
|
178
|
+
If ActiveSupport::StringInquirer is defined then the default `scope` is `"self".inquiry`.
|
179
|
+
The default value is `:self` if ActiveSupport::StringInquirer is not defined.
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
class MyObject
|
183
|
+
def inspect(scope: :self)
|
184
|
+
ObjectInspector::Inspector.inspect(self, scope: scope)
|
185
|
+
end
|
186
|
+
|
187
|
+
def inspect_flags(scope:, separator: " / ".freeze)
|
188
|
+
flags = ["FLAG1"]
|
189
|
+
|
190
|
+
# If ActiveSupport::StringInquirer is defined, use this:
|
191
|
+
# flags << "FLAG2" if scope.all?
|
192
|
+
|
193
|
+
# If ActiveSupport::StringInquirer is not defined, use this:
|
194
|
+
flags << "FLAG2" if scope == :all
|
195
|
+
|
196
|
+
flags.join(separator)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
MyObject.new.inspect # => "<MyObject[FLAG1]>"
|
201
|
+
MyObject.new.inspect(scope: :all) # => "<MyObject[FLAG1 / FLAG2]>"
|
202
|
+
```
|
203
|
+
|
204
|
+
|
205
|
+
## Custom Formatters
|
206
|
+
|
207
|
+
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/base_formatter.rb) and then passing that into ObjectInspector::Inspector.new.
|
208
|
+
|
209
|
+
```ruby
|
210
|
+
class MyCustomFormatter < ObjectInspector::BaseFormatter
|
211
|
+
def call
|
212
|
+
"(#{combine_strings})"
|
213
|
+
end
|
214
|
+
|
215
|
+
private
|
216
|
+
|
217
|
+
def build_identification_string(identification = self.identification)
|
218
|
+
identification.to_s
|
219
|
+
end
|
220
|
+
|
221
|
+
def build_flags_string(flags = self.flags)
|
222
|
+
" #{flags}" if flags
|
223
|
+
end
|
224
|
+
|
225
|
+
def build_info_string(info = self.info)
|
226
|
+
" (#{info})" if info
|
227
|
+
end
|
228
|
+
|
229
|
+
def build_name_string(name = self.name)
|
230
|
+
" -- #{name}" if name
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
class MyObject
|
235
|
+
include ObjectInspector::InspectorsHelper
|
236
|
+
|
237
|
+
def inspect
|
238
|
+
super(formatter: MyCustomFormatter)
|
239
|
+
end
|
240
|
+
|
241
|
+
private
|
242
|
+
|
243
|
+
def inspect_identification
|
244
|
+
"IDENTIFICATION"
|
245
|
+
end
|
246
|
+
|
247
|
+
def inspect_flags
|
248
|
+
"FLAG1"
|
249
|
+
end
|
250
|
+
|
251
|
+
def inspect_info
|
252
|
+
"INFO"
|
253
|
+
end
|
254
|
+
|
255
|
+
def inspect_name
|
256
|
+
"NAME"
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
MyObject.new.inspect # => "(IDENTIFICATION FLAG1 (INFO) -- NAME)"
|
261
|
+
```
|
262
|
+
|
263
|
+
See also: [ObjectInspector::DefaultFormatter](https://github.com/pdobb/object_inspector/blob/master/lib/object_inspector/default_formatter.rb).
|
264
|
+
|
265
|
+
|
266
|
+
## Supporting Libraries
|
267
|
+
|
268
|
+
ObjectInspector works great with the [ObjectIdentifier](https://github.com/pdobb/object_identifier) gem.
|
269
|
+
|
270
|
+
```ruby
|
271
|
+
class MyObject
|
272
|
+
include ObjectInspector::InspectorsHelper
|
273
|
+
|
274
|
+
def my_method1
|
275
|
+
"R1"
|
276
|
+
end
|
277
|
+
|
278
|
+
def my_method1
|
279
|
+
"R1"
|
280
|
+
end
|
281
|
+
|
282
|
+
private
|
283
|
+
|
284
|
+
def inspect_identification
|
285
|
+
identify(:m1, :m2)
|
286
|
+
end
|
287
|
+
|
288
|
+
def inspect_flags
|
289
|
+
"FLAG1"
|
290
|
+
end
|
291
|
+
|
292
|
+
def inspect_info
|
293
|
+
"INFO"
|
294
|
+
end
|
295
|
+
|
296
|
+
def inspect_name
|
297
|
+
"NAME"
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
MyObject.new.inspect # => "<MyObject[m1:R1, m2:R2][FLAG1] (INFO) :: NAME>"
|
302
|
+
```
|
303
|
+
|
304
|
+
|
305
|
+
## Development
|
306
|
+
|
307
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
308
|
+
|
309
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
310
|
+
|
311
|
+
|
312
|
+
## Contributing
|
313
|
+
|
314
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/pdobb/object_inspector.
|
315
|
+
|
316
|
+
|
317
|
+
## License
|
318
|
+
|
319
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "object_inspector"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
require "pry"
|
11
|
+
Pry.start
|
12
|
+
|
13
|
+
# require "irb"
|
14
|
+
# IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
module ObjectInspector
|
2
|
+
# ObjectInspector::BaseFormatter is an abstract base class that interfaces
|
3
|
+
# with {ObjectInspector::Inspector} objects to combine the supplied
|
4
|
+
# {#identification}, {#flags}, {#info}, and {#name} strings into a friendly
|
5
|
+
# "inspect" String.
|
6
|
+
#
|
7
|
+
# @attr inspector [ObjectInspector::Inspector]
|
8
|
+
class BaseFormatter
|
9
|
+
attr_reader :inspector
|
10
|
+
|
11
|
+
def initialize(inspector)
|
12
|
+
@inspector = inspector
|
13
|
+
end
|
14
|
+
|
15
|
+
# Perform the formatting routine.
|
16
|
+
#
|
17
|
+
# @return [String]
|
18
|
+
def call
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
|
22
|
+
# Delegates to {Inspector#identification}.
|
23
|
+
#
|
24
|
+
# @return [String] if given
|
25
|
+
def identification
|
26
|
+
@inspector.identification
|
27
|
+
end
|
28
|
+
|
29
|
+
# Delegates to {Inspector#flags}.
|
30
|
+
#
|
31
|
+
# @return [String] if given
|
32
|
+
# @return [NilClass] if not given
|
33
|
+
def flags
|
34
|
+
@inspector.flags
|
35
|
+
end
|
36
|
+
|
37
|
+
# Delegates to {Inspector#info}.
|
38
|
+
#
|
39
|
+
# @return [String] if given
|
40
|
+
# @return [NilClass] if not given
|
41
|
+
def info
|
42
|
+
@inspector.info
|
43
|
+
end
|
44
|
+
|
45
|
+
# Delegates to {Inspector#name}.
|
46
|
+
#
|
47
|
+
# @return [String] if given
|
48
|
+
# @return [NilClass] if not given
|
49
|
+
def name
|
50
|
+
@inspector.name
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def combine_strings
|
56
|
+
strings.join
|
57
|
+
end
|
58
|
+
|
59
|
+
# Override in subclasses as needed.
|
60
|
+
def strings
|
61
|
+
[
|
62
|
+
build_identification_string,
|
63
|
+
build_flags_string,
|
64
|
+
build_info_string,
|
65
|
+
build_name_string,
|
66
|
+
].compact
|
67
|
+
end
|
68
|
+
|
69
|
+
def build_identification_string(*)
|
70
|
+
raise NotImplementedError
|
71
|
+
end
|
72
|
+
|
73
|
+
def build_flags_string(*)
|
74
|
+
raise NotImplementedError
|
75
|
+
end
|
76
|
+
|
77
|
+
def build_info_string(*)
|
78
|
+
raise NotImplementedError
|
79
|
+
end
|
80
|
+
|
81
|
+
def build_name_string(*)
|
82
|
+
raise NotImplementedError
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ObjectInspector
|
2
|
+
# ObjectInspector::DefaultFormatter implements
|
3
|
+
# {ObjectInspector::BaseFormatter} to return a standard/default inspect output
|
4
|
+
# format.
|
5
|
+
#
|
6
|
+
# @attr (see BaseFormatter)
|
7
|
+
class DefaultFormatter < BaseFormatter
|
8
|
+
# Perform the formatting routine.
|
9
|
+
#
|
10
|
+
# @return [String]
|
11
|
+
def call
|
12
|
+
"<#{combine_strings}>"
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def build_identification_string(identification = self.identification)
|
18
|
+
identification.to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
def build_flags_string(flags = self.flags)
|
22
|
+
"[#{flags.to_s.upcase}]" if flags
|
23
|
+
end
|
24
|
+
|
25
|
+
def build_info_string(info = self.info)
|
26
|
+
" (#{info})" if info
|
27
|
+
end
|
28
|
+
|
29
|
+
def build_name_string(name = self.name)
|
30
|
+
" :: #{name}" if name
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module ObjectInspector
|
2
|
+
# ObjectInspector organizes inspection of the associated {#object} via the
|
3
|
+
# passed in options and via a {ObjectInspector::BaseFormatter} instance.
|
4
|
+
#
|
5
|
+
# @attr object [Object] the object being inspected
|
6
|
+
# @attr scope [Symbol] Object inspection type. For example:
|
7
|
+
# :self (default) -- Means: Only interrogate self; Don't interrogate
|
8
|
+
# neighboring objects
|
9
|
+
# :all -- Means: Interrogate self as well as neighboring objects
|
10
|
+
# <custom> -- Any value that {#object} recognizes can mean anything
|
11
|
+
# that makes sense for {#object}
|
12
|
+
# @attr formatter [ObjectInspector::BaseFormatter] the formatter object to use
|
13
|
+
# for combining the output of into the inspect String
|
14
|
+
# @attr kargs [Hash] options to be sent to {#object}
|
15
|
+
class Inspector
|
16
|
+
attr_reader :object,
|
17
|
+
:scope,
|
18
|
+
:formatter_klass,
|
19
|
+
:kargs
|
20
|
+
|
21
|
+
# The prefix for all methods called on {#object} for inspect
|
22
|
+
# details/strings.
|
23
|
+
def self.object_method_prefix
|
24
|
+
"inspect".freeze
|
25
|
+
end
|
26
|
+
|
27
|
+
# Shortcuts the instantiation -> {#to_s} flow that would normally be
|
28
|
+
# required to use ObjectInspector::Inspector.
|
29
|
+
#
|
30
|
+
# @return [String]
|
31
|
+
def self.inspect(object, **kargs)
|
32
|
+
new(object, **kargs).to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(
|
36
|
+
object,
|
37
|
+
scope: :self,
|
38
|
+
formatter: DefaultFormatter,
|
39
|
+
**kargs)
|
40
|
+
@object = object
|
41
|
+
@formatter_klass = formatter
|
42
|
+
@scope = "".respond_to?(:inquiry) ? scope.to_s.inquiry : scope.to_sym
|
43
|
+
@kargs = kargs
|
44
|
+
end
|
45
|
+
|
46
|
+
# Generate the formatted inspect String.
|
47
|
+
#
|
48
|
+
# @return [String]
|
49
|
+
def to_s
|
50
|
+
formatter.call
|
51
|
+
end
|
52
|
+
|
53
|
+
# Core object identification details, such as the {#object} class name and
|
54
|
+
# any core-level attributes.
|
55
|
+
#
|
56
|
+
# @return [String]
|
57
|
+
def identification
|
58
|
+
(value(key: :identification) || object.class).to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
# Boolean flags/states applicable to {#object}.
|
62
|
+
#
|
63
|
+
# @return [String] if given
|
64
|
+
# @return [NilClass] if not given
|
65
|
+
def flags
|
66
|
+
value(key: :flags)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Informational details applicable to {#object}.
|
70
|
+
#
|
71
|
+
# @return [String] if given
|
72
|
+
# @return [NilClass] if not given
|
73
|
+
def info
|
74
|
+
value(key: :info)
|
75
|
+
end
|
76
|
+
|
77
|
+
# The generally human-friendly unique identifier for {#object}.
|
78
|
+
# @return [String] if given
|
79
|
+
# @return [NilClass] if not given
|
80
|
+
def name
|
81
|
+
value(key: :name)
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def formatter
|
87
|
+
formatter_klass.new(self)
|
88
|
+
end
|
89
|
+
|
90
|
+
# @return [String] if `key` is found in {#kargs} or if {#object} responds to
|
91
|
+
# `#{object_method_prefix}_#{key}` (e.g. `inspect_flags`)
|
92
|
+
# @return [NilClass] if not found in {#kargs} or {#object}
|
93
|
+
def value(key:)
|
94
|
+
result = kargs.fetch(key) { interrogate_object(key) }
|
95
|
+
|
96
|
+
result.to_s if result
|
97
|
+
end
|
98
|
+
|
99
|
+
# @return [String] if {#object} responds to `#{object_method_prefix}_#{key}`
|
100
|
+
# (e.g. `inspect_flags`)
|
101
|
+
# @return [NilClass] if not found on {#object}
|
102
|
+
def interrogate_object(key)
|
103
|
+
interrogator =
|
104
|
+
ObjectInterrogator.new(
|
105
|
+
object: object,
|
106
|
+
method_name: build_method_name(key),
|
107
|
+
kargs: object_method_keyword_arguments)
|
108
|
+
|
109
|
+
interrogator.call
|
110
|
+
end
|
111
|
+
|
112
|
+
def build_method_name(key)
|
113
|
+
"#{object_method_prefix}_#{key}"
|
114
|
+
end
|
115
|
+
|
116
|
+
def object_method_prefix
|
117
|
+
self.class.object_method_prefix
|
118
|
+
end
|
119
|
+
|
120
|
+
def object_method_keyword_arguments
|
121
|
+
{
|
122
|
+
scope: scope,
|
123
|
+
}
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ObjectInspector
|
2
|
+
# ObjectInspector::InspectorsHelper can be included into any object to
|
3
|
+
# simplify the process of instantiating an ObjectInspector::Inspector and
|
4
|
+
# generating the inspection output.
|
5
|
+
module InspectorsHelper
|
6
|
+
# Calls {ObjectInspector::Inspector.inspect} on the passed in `object`,
|
7
|
+
# passing it the passed in `kargs` (keyword arguments).
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
def inspect(object = self, **kargs)
|
11
|
+
Inspector.inspect(object, **kargs)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module ObjectInspector
|
2
|
+
# ObjectInspector::ObjectInterrogator collaborates with {#object} to return
|
3
|
+
# Object#{#method_name} if {#object} responds to the method.
|
4
|
+
#
|
5
|
+
# If Object#{#method_name} accepts the supplied {#kargs} then they are passed
|
6
|
+
# in as well. If not, then any supplied {#kargs} will be ignored.
|
7
|
+
class ObjectInterrogator
|
8
|
+
attr_reader :object,
|
9
|
+
:method_name,
|
10
|
+
:kargs
|
11
|
+
|
12
|
+
def initialize(object:, method_name:, kargs: {})
|
13
|
+
@object = object
|
14
|
+
@method_name = method_name
|
15
|
+
@kargs = kargs
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [String, ...] whatever type Object#{#method} returns
|
19
|
+
#
|
20
|
+
# @raise [ArgumentError] if Object#{#method} has an unexpected method
|
21
|
+
# signature
|
22
|
+
def call
|
23
|
+
return unless object_responds_to_method_name?
|
24
|
+
|
25
|
+
object.send(method_name, **kargs)
|
26
|
+
rescue ArgumentError
|
27
|
+
object.send(method_name)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def object_responds_to_method_name?(include_private: true)
|
33
|
+
object.respond_to?(method_name, include_private)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "object_inspector/version"
|
2
|
+
|
3
|
+
# ObjectInspector is the base namespace for all modules/classes related to the
|
4
|
+
# object_inspector gem.
|
5
|
+
module ObjectInspector
|
6
|
+
autoload :Inspector, "object_inspector/inspector"
|
7
|
+
autoload :ObjectInterrogator, "object_inspector/object_interrogator"
|
8
|
+
autoload :BaseFormatter, "object_inspector/base_formatter"
|
9
|
+
autoload :DefaultFormatter, "object_inspector/default_formatter"
|
10
|
+
autoload :InspectorsHelper, "object_inspector/inspectors_helper"
|
11
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "object_inspector/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "object_inspector"
|
8
|
+
spec.version = ObjectInspector::VERSION
|
9
|
+
spec.authors = ["Paul Dobbins"]
|
10
|
+
spec.email = ["paul.dobbins@icloud.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{ObjectInspector generates uniformly formatted inspect output with customizable amounts of detail.}
|
13
|
+
spec.description = %q{ObjectInspector takes Object#inspect to the next level. Specify any combination of identification attributes, flags, info, and/or a name along with a self-definable scope option to represent an object in the console, in logging, or otherwise.}
|
14
|
+
spec.homepage = "https://github.com/pdobb/object_inspector"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
# if spec.respond_to?(:metadata)
|
20
|
+
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
21
|
+
# else
|
22
|
+
# raise "RubyGems 2.0 or newer is required to protect against " \
|
23
|
+
# "public gem pushes."
|
24
|
+
# end
|
25
|
+
|
26
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
27
|
+
f.match(%r{^(test|spec|features)/})
|
28
|
+
end
|
29
|
+
spec.bindir = "exe"
|
30
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
|
+
spec.require_paths = ["lib"]
|
32
|
+
|
33
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
34
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
35
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
36
|
+
spec.add_development_dependency "simplecov", "~> 0.16"
|
37
|
+
spec.add_development_dependency "byebug", "~> 10.0"
|
38
|
+
spec.add_development_dependency "pry", "~> 0.11"
|
39
|
+
spec.add_development_dependency "pry-byebug", "~> 3.6"
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: object_inspector
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Paul Dobbins
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-04-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.16'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.16'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.16'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.16'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: byebug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.11'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.11'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry-byebug
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.6'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.6'
|
111
|
+
description: ObjectInspector takes Object#inspect to the next level. Specify any combination
|
112
|
+
of identification attributes, flags, info, and/or a name along with a self-definable
|
113
|
+
scope option to represent an object in the console, in logging, or otherwise.
|
114
|
+
email:
|
115
|
+
- paul.dobbins@icloud.com
|
116
|
+
executables: []
|
117
|
+
extensions: []
|
118
|
+
extra_rdoc_files: []
|
119
|
+
files:
|
120
|
+
- ".gitignore"
|
121
|
+
- ".travis.yml"
|
122
|
+
- CHANGELOG.md
|
123
|
+
- Gemfile
|
124
|
+
- Gemfile.lock
|
125
|
+
- LICENSE.txt
|
126
|
+
- README.md
|
127
|
+
- Rakefile
|
128
|
+
- bin/console
|
129
|
+
- bin/setup
|
130
|
+
- lib/object_inspector.rb
|
131
|
+
- lib/object_inspector/base_formatter.rb
|
132
|
+
- lib/object_inspector/default_formatter.rb
|
133
|
+
- lib/object_inspector/inspector.rb
|
134
|
+
- lib/object_inspector/inspectors_helper.rb
|
135
|
+
- lib/object_inspector/object_interrogator.rb
|
136
|
+
- lib/object_inspector/version.rb
|
137
|
+
- object_inspector.gemspec
|
138
|
+
homepage: https://github.com/pdobb/object_inspector
|
139
|
+
licenses:
|
140
|
+
- MIT
|
141
|
+
metadata: {}
|
142
|
+
post_install_message:
|
143
|
+
rdoc_options: []
|
144
|
+
require_paths:
|
145
|
+
- lib
|
146
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
153
|
+
- - ">="
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0'
|
156
|
+
requirements: []
|
157
|
+
rubyforge_project:
|
158
|
+
rubygems_version: 2.7.6
|
159
|
+
signing_key:
|
160
|
+
specification_version: 4
|
161
|
+
summary: ObjectInspector generates uniformly formatted inspect output with customizable
|
162
|
+
amounts of detail.
|
163
|
+
test_files: []
|