class Study::TreeNode
Attributes
type[RW]
value[RW]
Public Class Methods
convert(target, registered_objects: [])
click to toggle source
# File lib/study/tree_node.rb, line 135 def self.convert(target, registered_objects: []) if registered_objects.include?(target.object_id) return TreeNode.new(type: target.class.name, value: "DUPLICATE #{ target.class.name }") else if target.is_a?(Array) || target.is_a?(Hash) || target.instance_variables.size > 0 registered_objects << target.object_id end end output = { type: nil, value: nil } target_class_name = target.class.name if target.is_a?(Hash) output_container = {} target.each do |hash_key, hash_value| output_container[hash_key] = convert(hash_value, registered_objects: registered_objects) end output[:value] = output_container elsif target.is_a?(Array) output_container = {} target.each_with_index do |array_value, index| output_container[index] = convert(array_value, registered_objects: registered_objects) end output[:value] = output_container elsif target.instance_variables.size > 0 output_container = {} target.instance_variables.each do |name| value = target.instance_variable_get(name) key = name.to_s.gsub('@', '').to_sym # use getter method instead if target.public_methods(false).include?(key.to_sym) begin output_container[key] = convert(target.send(key.to_sym), registered_objects: registered_objects) rescue output_container[key] = convert(value, registered_objects: registered_objects) end else output_container[key] = convert(value, registered_objects: registered_objects) end end output[:value] = output_container elsif target_class_name == "NilClass" output[:value] = "nil" elsif target_class_name == "IO" output[:value] = "<IO>" elsif target_class_name == "Thread::Mutex" output[:value] = "<Thread::Mutex>" elsif target_class_name == "Proc" output[:value] = "<Proc>" else output[:value] = target end output[:type] = target_class_name TreeNode.new(type: output[:type], value: output[:value]) end
new(type:, value:)
click to toggle source
# File lib/study/tree_node.rb, line 5 def initialize(type:, value:) @type = type @value = value end
Public Instance Methods
==(other)
click to toggle source
# File lib/study/tree_node.rb, line 10 def ==(other) @type == other.type && @value == other.value end
draw(indent: 0, tree_key: nil, branch_toggle: [], max_depth: 10, plain: false)
click to toggle source
# File lib/study/tree_node.rb, line 34 def draw(indent: 0, tree_key: nil, branch_toggle: [], max_depth: 10, plain: false) return if indent > max_depth if indent == 0 if has_children? draw_line(indent: 0, text: TextHighlight.yellow(@type, plain: plain), branch_toggle: branch_toggle, root: true, max_depth: max_depth,) else draw_line(indent: 0, text: [TextHighlight.yellow(@type, plain: plain), TextHighlight.white(@value, plain: plain)].join(" "), branch_toggle: branch_toggle, root: true, max_depth: max_depth) return end end if has_children? if tree_key draw_line(indent: indent, text: highlight(left: tree_key, right: @type, nested: true, plain: plain), branch_toggle: branch_toggle, no_children: false, max_depth: max_depth, plain: plain) end each_child_with_last do |key, value, last| if value.is_a?(TreeNode) value.draw(indent: indent + 1, tree_key: key, branch_toggle: branch_toggle + [last], max_depth: max_depth, plain: plain) else draw_line(indent: indent + 1, text: highlight(left: key, right: value, plain: plain), branch_toggle: branch_toggle + [last], max_depth: max_depth, plain: plain) end end else draw_line(indent: indent, text: highlight(left: tree_key, right: @value, plain: plain), branch_toggle: branch_toggle, max_depth: max_depth, plain: plain) end nil end
draw_line(indent: 0, text:, branch_toggle:, root: false, no_children: true, max_depth: 10, plain: false)
click to toggle source
# File lib/study/tree_node.rb, line 111 def draw_line(indent: 0, text:, branch_toggle:, root: false, no_children: true, max_depth: 10, plain: false) if root puts text else previous, current = branch_toggle[0..-2], branch_toggle[-1] indent_lines = previous.map { |item| item ? " " : " │" }.join("") current_branch_line = current ? " └── " : " ├── " branch_lines = TextHighlight.green([indent_lines, current_branch_line].join(""), plain: plain) puts [branch_lines, text.force_encoding('UTF-8')].join("") if current && (no_children || (indent >= max_depth)) puts TextHighlight.green([indent_lines].join(""), plain: plain) end end end
each_child_with_last(&block)
click to toggle source
# File lib/study/tree_node.rb, line 92 def each_child_with_last(&block) total_size = @value.size sorted_keys = @value.keys.sort sorted_number_keys = sorted_keys.select { |key| key.is_a?(Numeric) }.sort sorted_symbol_keys = sorted_keys.select { |key| key.is_a?(Symbol) }.sort sorted_string_keys = sorted_keys.select { |key| key.is_a?(String) }.sort remaining_keys = sorted_keys - sorted_number_keys - sorted_symbol_keys - sorted_string_keys remaining_keys = remaining_keys.sort rescue remaining_keys sorted_keys = sorted_number_keys + sorted_symbol_keys + sorted_string_keys + remaining_keys sorted_keys.each_with_index do |key, index| value = @value[key] block.call(key, value, total_size - 1 == index) end end
has_children?()
click to toggle source
# File lib/study/tree_node.rb, line 131 def has_children? ["Hash", "Array"].include?(@value.class.name) && @value.size > 0 end
highlight(left: nil, right: nil, nested: false, plain: false)
click to toggle source
# File lib/study/tree_node.rb, line 14 def highlight(left: nil, right: nil, nested: false, plain: false) colored_left = left.is_a?(Integer) ? TextHighlight.violet(left, plain: plain) : TextHighlight.cyan(left, plain: plain) if nested [ colored_left, TextHighlight.green(":", plain: plain), " ", TextHighlight.yellow(right, plain: plain) ].join("") else [ colored_left, TextHighlight.green(":", plain: plain), " ", TextHighlight.white(right, plain: plain) ].join("") end end