study 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 +7 -0
- data/lib/study.rb +14 -0
- data/lib/study/text_highlight.rb +33 -0
- data/lib/study/tree_node.rb +200 -0
- data/lib/study/version.rb +3 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: df597f9ef5df8f0f8772deef6ba1c2cd163fa3b4
|
4
|
+
data.tar.gz: 206609780a7246e7e966c2fb6cc8923fefc6ffcb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b26ca74f73016fda6cb5074e95c13d8d25f5a40c3c12cfb8f6685272c9487990978eef2d1f9cedba3b3b8e80b9655d0e21e15a4c102c2bcf365358f3a20c75d5
|
7
|
+
data.tar.gz: b2171cfe86784a5fcb4afe044cb8c183cf8e088dbd949e717578d0b4069503a3e16b55566f5884af4cf3bab51e5c9a552b7a08b109e6e61c680d351d7cea4161
|
data/lib/study.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'study/text_highlight'
|
2
|
+
require 'study/tree_node'
|
3
|
+
require 'study/version'
|
4
|
+
|
5
|
+
module Study
|
6
|
+
module Methods
|
7
|
+
def study(target, max_depth: 10, plain: false)
|
8
|
+
TreeNode.convert(target).draw(max_depth: max_depth, plain: plain)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
extend Study::Methods
|
14
|
+
include Study::Methods
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Study
|
2
|
+
module TextHighlight
|
3
|
+
class << self
|
4
|
+
def red(string, plain: false)
|
5
|
+
plain ? string.to_s : "\033[1;31;40m#{ string.to_s }\033[0m"
|
6
|
+
end
|
7
|
+
|
8
|
+
def yellow(string, plain: false)
|
9
|
+
plain ? string.to_s : "\033[1;33;40m#{ string.to_s }\033[0m"
|
10
|
+
end
|
11
|
+
|
12
|
+
def blue(string, plain: false)
|
13
|
+
plain ? string.to_s : "\033[1;34;40m#{ string.to_s }\033[0m"
|
14
|
+
end
|
15
|
+
|
16
|
+
def green(string, plain: false)
|
17
|
+
plain ? string.to_s : "\033[1;32;40m#{ string.to_s }\033[0m"
|
18
|
+
end
|
19
|
+
|
20
|
+
def violet(string, plain: false)
|
21
|
+
plain ? string.to_s : "\033[1;35;40m#{ string.to_s }\033[0m"
|
22
|
+
end
|
23
|
+
|
24
|
+
def cyan(string, plain: false)
|
25
|
+
plain ? string.to_s : "\033[1;36;40m#{ string.to_s }\033[0m"
|
26
|
+
end
|
27
|
+
|
28
|
+
def white(string, plain: false)
|
29
|
+
plain ? string.to_s : "\033[1;37;40m#{ string.to_s }\033[0m"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
module Study
|
2
|
+
class TreeNode
|
3
|
+
attr_accessor :type, :value
|
4
|
+
|
5
|
+
def initialize(type:, value:)
|
6
|
+
@type = type
|
7
|
+
@value = value
|
8
|
+
end
|
9
|
+
|
10
|
+
def ==(other)
|
11
|
+
@type == other.type && @value == other.value
|
12
|
+
end
|
13
|
+
|
14
|
+
def highlight(left: nil, right: nil, nested: false, plain: false)
|
15
|
+
colored_left = left.is_a?(Integer) ? TextHighlight.violet(left, plain: plain) : TextHighlight.cyan(left, plain: plain)
|
16
|
+
|
17
|
+
if nested
|
18
|
+
[
|
19
|
+
colored_left,
|
20
|
+
TextHighlight.green(":", plain: plain),
|
21
|
+
" ",
|
22
|
+
TextHighlight.yellow(right, plain: plain)
|
23
|
+
].join("")
|
24
|
+
else
|
25
|
+
[
|
26
|
+
colored_left,
|
27
|
+
TextHighlight.green(":", plain: plain),
|
28
|
+
" ",
|
29
|
+
TextHighlight.white(right, plain: plain)
|
30
|
+
].join("")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def draw(indent: 0, tree_key: nil, branch_toggle: [], max_depth: 10, plain: false)
|
35
|
+
return if indent > max_depth
|
36
|
+
|
37
|
+
if indent == 0
|
38
|
+
if has_children?
|
39
|
+
draw_line(indent: 0,
|
40
|
+
text: TextHighlight.yellow(@type, plain: plain),
|
41
|
+
branch_toggle: branch_toggle,
|
42
|
+
root: true,
|
43
|
+
max_depth: max_depth,)
|
44
|
+
|
45
|
+
else
|
46
|
+
draw_line(indent: 0,
|
47
|
+
text: [TextHighlight.yellow(@type, plain: plain), TextHighlight.white(@value, plain: plain)].join(" "),
|
48
|
+
branch_toggle: branch_toggle,
|
49
|
+
root: true,
|
50
|
+
max_depth: max_depth)
|
51
|
+
|
52
|
+
return
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
if has_children?
|
57
|
+
if tree_key
|
58
|
+
draw_line(indent: indent,
|
59
|
+
text: highlight(left: tree_key, right: @type, nested: true, plain: plain),
|
60
|
+
branch_toggle: branch_toggle,
|
61
|
+
no_children: false,
|
62
|
+
max_depth: max_depth,
|
63
|
+
plain: plain)
|
64
|
+
end
|
65
|
+
|
66
|
+
each_child_with_last do |key, value, last|
|
67
|
+
if value.is_a?(TreeNode)
|
68
|
+
value.draw(indent: indent + 1,
|
69
|
+
tree_key: key,
|
70
|
+
branch_toggle: branch_toggle + [last],
|
71
|
+
max_depth: max_depth,
|
72
|
+
plain: plain)
|
73
|
+
else
|
74
|
+
draw_line(indent: indent + 1,
|
75
|
+
text: highlight(left: key, right: value, plain: plain),
|
76
|
+
branch_toggle: branch_toggle + [last],
|
77
|
+
max_depth: max_depth,
|
78
|
+
plain: plain)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
else
|
82
|
+
draw_line(indent: indent,
|
83
|
+
text: highlight(left: tree_key, right: @value, plain: plain),
|
84
|
+
branch_toggle: branch_toggle,
|
85
|
+
max_depth: max_depth,
|
86
|
+
plain: plain)
|
87
|
+
end
|
88
|
+
|
89
|
+
nil
|
90
|
+
end
|
91
|
+
|
92
|
+
def each_child_with_last(&block)
|
93
|
+
total_size = @value.size
|
94
|
+
sorted_keys = @value.keys.sort
|
95
|
+
|
96
|
+
sorted_keys.each_with_index do |key, index|
|
97
|
+
value = @value[key]
|
98
|
+
|
99
|
+
block.call(key, value, total_size - 1 == index)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def draw_line(indent: 0, text:, branch_toggle:, root: false, no_children: true, max_depth: 10, plain: false)
|
104
|
+
if root
|
105
|
+
puts text
|
106
|
+
else
|
107
|
+
previous, current = branch_toggle[0..-2], branch_toggle[-1]
|
108
|
+
|
109
|
+
indent_lines = previous.map { |item| item ? " " : " │" }.join("")
|
110
|
+
|
111
|
+
current_branch_line = current ? " └── " : " ├── "
|
112
|
+
|
113
|
+
branch_lines = TextHighlight.green([indent_lines, current_branch_line].join(""), plain: plain)
|
114
|
+
|
115
|
+
puts [branch_lines, text].join("")
|
116
|
+
|
117
|
+
if current && (no_children || (indent >= max_depth))
|
118
|
+
puts TextHighlight.green([indent_lines].join(""), plain: plain)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def has_children?
|
124
|
+
["Hash", "Array"].include?(@value.class.name)
|
125
|
+
end
|
126
|
+
|
127
|
+
def self.convert(target, registered_objects: [])
|
128
|
+
if registered_objects.include?(target.object_id)
|
129
|
+
return TreeNode.new(type: target.class.name, value: "DUPLICATE #{ target.class.name }")
|
130
|
+
else
|
131
|
+
if target.is_a?(Array) || target.is_a?(Hash) || target.instance_variables.size > 0
|
132
|
+
registered_objects << target.object_id
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
output = {
|
137
|
+
type: nil,
|
138
|
+
value: nil
|
139
|
+
}
|
140
|
+
|
141
|
+
target_class_name = target.class.name
|
142
|
+
|
143
|
+
if target.is_a?(Hash)
|
144
|
+
output_container = {}
|
145
|
+
|
146
|
+
target.each do |hash_key, hash_value|
|
147
|
+
output_container[hash_key] = convert(hash_value, registered_objects: registered_objects)
|
148
|
+
end
|
149
|
+
|
150
|
+
output[:value] = output_container
|
151
|
+
|
152
|
+
elsif target.is_a?(Array)
|
153
|
+
output_container = {}
|
154
|
+
|
155
|
+
target.each_with_index do |array_value, index|
|
156
|
+
output_container[index] = convert(array_value, registered_objects: registered_objects)
|
157
|
+
end
|
158
|
+
|
159
|
+
output[:value] = output_container
|
160
|
+
|
161
|
+
elsif target.instance_variables.size > 0
|
162
|
+
output_container = {}
|
163
|
+
|
164
|
+
target.instance_variables.each do |name|
|
165
|
+
value = target.instance_variable_get(name)
|
166
|
+
key = name.to_s.gsub('@', '').to_sym
|
167
|
+
|
168
|
+
# use getter method instead
|
169
|
+
if target.public_methods(false).include?(key.to_sym)
|
170
|
+
output_container[key] = convert(target.send(key.to_sym), registered_objects: registered_objects)
|
171
|
+
else
|
172
|
+
output_container[key] = convert(value, registered_objects: registered_objects)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
output[:value] = output_container
|
177
|
+
|
178
|
+
elsif target_class_name == "NilClass"
|
179
|
+
output[:value] = "nil"
|
180
|
+
|
181
|
+
elsif target_class_name == "IO"
|
182
|
+
output[:value] = "<IO>"
|
183
|
+
|
184
|
+
elsif target_class_name == "Thread::Mutex"
|
185
|
+
output[:value] = "<Thread::Mutex>"
|
186
|
+
|
187
|
+
elsif target_class_name == "Proc"
|
188
|
+
output[:value] = "<Proc>"
|
189
|
+
|
190
|
+
else
|
191
|
+
output[:value] = target
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
output[:type] = target_class_name
|
196
|
+
|
197
|
+
TreeNode.new(type: output[:type], value: output[:value])
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: study
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joshua Arvin Lat
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-01-01 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.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Study Ruby objects, hashes, and arrays by exposing their internal structure
|
42
|
+
with trees, colors, and indentation
|
43
|
+
email:
|
44
|
+
- joshua.arvin.lat@gmail.com
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- lib/study.rb
|
50
|
+
- lib/study/text_highlight.rb
|
51
|
+
- lib/study/tree_node.rb
|
52
|
+
- lib/study/version.rb
|
53
|
+
homepage: ''
|
54
|
+
licenses:
|
55
|
+
- MIT
|
56
|
+
metadata: {}
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options: []
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
requirements: []
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 2.6.8
|
74
|
+
signing_key:
|
75
|
+
specification_version: 4
|
76
|
+
summary: Study Ruby objects, hashes, and arrays by exposing their internal structure
|
77
|
+
with trees, colors, and indentation
|
78
|
+
test_files: []
|