lib/debug_helper.rb in debug_helper-1.7.0 vs lib/debug_helper.rb in debug_helper-1.8.0
- old
+ new
@@ -1,10 +1,34 @@
+require 'ostruct'
require 'set'
require 'yaml'
-require 'debug_helper/version'
+require_relative 'debug_helper/version'
+require_relative 'debug_helper/handler'
+
+ require_relative 'debug_helper/each_with_index_handler'
+ require_relative 'debug_helper/array_handler'
+ require_relative 'debug_helper/set_handler'
+
+ require_relative 'debug_helper/each_pair_handler'
+ require_relative 'debug_helper/hash_handler'
+ require_relative 'debug_helper/struct_handler'
+
+ require_relative 'debug_helper/dir_handler'
+ require_relative 'debug_helper/exception_handler'
+ require_relative 'debug_helper/file_handler'
+ require_relative 'debug_helper/generic_handler'
+ require_relative 'debug_helper/io_handler'
+ require_relative 'debug_helper/match_data_handler'
+ require_relative 'debug_helper/object_handler'
+ require_relative 'debug_helper/open_struct_handler'
+ require_relative 'debug_helper/regexp_handler'
+ require_relative 'debug_helper/string_handler'
+ require_relative 'debug_helper/symbol_handler'
+ require_relative 'debug_helper/range_handler'
+
class DebugHelper
module Putd
def putd(obj, message, options = {})
@@ -19,185 +43,80 @@
:object_ids,
:depth
def self.show(obj, message = obj.class, options = {})
debug_helper = DebugHelper.new(obj, message, options)
- x = debug_helper.send(:_show, obj, message, info = {})
- puts x.to_yaml
+ s = debug_helper.show(obj, message, info = {})
+ puts s.to_yaml
end
- private
-
def initialize(obj, message, options)
self.obj = obj
self.message = message
self.depth = options[:depth] || 3
self.object_ids = []
end
- def _show(obj, message, info)
- if object_ids.include?(obj.object_id)
- s = show_object(obj, message, info)
- elsif depth == object_ids.size
- s = show_object(obj, message, info)
- else
- object_ids.push(obj.object_id)
- s = case
- when obj.kind_of?(Array)
- show_array(obj, message, info)
- when obj.kind_of?(Hash)
- show_hash(obj, message, info)
- when obj.kind_of?(Set)
- show_array(obj, message, info)
- when obj.kind_of?(Struct)
- show_struct(obj, message, info)
- # when obj.kind_of?(Range)
- else
- show_object(obj, message, info)
- end
- object_ids.pop
- end
- s
+ def object_seen?(obj)
+ object_ids.include?(obj.object_id)
end
- def show_array(obj, message, info)
- content = {}
- obj.each_with_index do |item, i|
- content.store("Element #{i}", _show(item, nil, {}))
- end
- attrs = {
- :message => message,
- :size => obj.size,
- }
- _show_item(obj.class.name, content, attrs, info)
+ def depth_reached?
+ depth == object_ids.size
end
- def show_hash(obj, message, info)
- content = {}
- obj.each_with_index do |pair, i|
- key, value = *pair
- pair = {'Key' => _show(key, nil, {}), 'Value' => _show(value, nil, {})}
- content.store("Pair #{i}", pair)
- end
- attrs = {
- :size => obj.size,
- :default => obj.default,
- :default_proc => obj.default_proc,
- :message => message,
- }
- _show_item(obj.class.name, content, attrs, info)
- end
-
- def show_object(obj, message, info)
- methods = methods_for_object(obj)
- if methods.nil?
- message_info = message.nil? ? '' : " (message='#{message}')"
- "#{obj.class.name}#{message_info} #{obj.inspect}"
+ def show(obj, message, info)
+ handler = nil
+ if object_seen?(obj) || depth_reached?
+ handler = GenericHandler.new(self, obj, message, info)
+ s = handler.show
else
- content = {}
- attrs = {:message => message}
- methods[:instance].each do |instance_method|
- value = obj.send(instance_method)
- if instance_method == :size
- attrs.store(:size, value)
+ object_ids.push(obj.object_id)
+ begin
+ # If there's a handler for the class, use it.
+ # Note that the class may be a custom class, not defined here,
+ # but instead defined outside this project.
+ # So if the user of this library has defined DebugHelper::FooHandler
+ # and the object is a Foo, that handler will be selected and called.
+ handler_class_name = "DebugHelper::#{obj.class.name}Handler"
+ handler_class = Object.const_get(handler_class_name)
+ handler = handler_class.new(method(__method__), obj, message, info)
+ rescue
+ # If there's not a handler for the class, try using :kind_of?.
+ [
+ Array,
+ Dir,
+ Exception,
+ File,
+ IO,
+ Hash,
+ OpenStruct,
+ Range,
+ Set,
+ String,
+ Struct,
+ # There's no method Symbol.new, so cannot instantiate a subclass.
+ # Symbol,
+ ].each do |klass|
+ if obj.kind_of?(klass)
+ handler_class_name = "DebugHelper::#{klass.name}Handler"
+ handler_class = Object.const_get(handler_class_name)
+ handler = handler_class.new(method(__method__), obj, message, info)
+ break
+ end
+ end
+ end
+ if handler.nil?
+ if obj.instance_of?(Object)
+ handler_class= ObjectHandler
else
- content.store(instance_method.to_s, value)
+ handler_class = GenericHandler
end
+ handler = handler_class.new(self, obj, message, info)
end
- methods[:class].each do |pair|
- class_method, arguments = *pair
- value = Object.const_get(obj.class.to_s).send(class_method, *arguments)
- content.store(class_method.to_s, value)
- end
- _show_item(obj.class.name, content, attrs, info)
+ s = handler.show
+ object_ids.pop
end
- end
-
- def show_struct(obj, message, info)
- content = {}
- i = 0
- obj.each_pair do |member|
- member_name, value = *member
- pair = {'Name' => member_name, 'Value' => _show(value, nil, {})}
- content.store("Member #{i}", pair)
- i += 1
- end
- attrs = {
- :message => message,
- :size => obj.size,
- }
- _show_item(obj.class.name, content, attrs, info)
- end
-
- def _show_item(class_name, content, attrs, info)
- message = attrs[:message]
- unless message.nil?
- attrs[:message] = "'#{message}'"
- end
- label = label(class_name, attrs)
- info.store(label, content)
- info
- end
-
- def label(class_name, attrs)
- a = []
- attrs.each_pair do |key, value|
- a.push("#{key}=#{value}") unless value.nil?
- end
- return class_name if a.empty?
- attrs_s = a.join(' ')
- "#{class_name} (#{attrs_s})"
- end
-
- def methods_for_object(obj)
- methods = case
- when obj.kind_of?(File)
- {
- # The instance forms of some of these require the file to be open.
- :class => {
- :absolute_path => [obj.path],
- :atime => [obj.path],
- :ctime => [obj.path],
- :executable? => [obj.path],
- :exist? => [obj.path],
- :ftype => [obj.path],
- :mtime => [obj.path],
- :path => [obj.path],
- :pipe? => [obj.path],
- :readable? => [obj.path],
- :realpath => [obj.path],
- :setgid? => [obj.path],
- :setuid? => [obj.path],
- :size => [obj.path],
- :socket? => [obj.path],
- :symlink? => [obj.path],
- :writable? => [obj.path],
- },
- :instance => [],
- }
- when obj.kind_of?(String)
- {
- :class => {},
- :instance => [
- :to_s,
- :size,
- :encoding,
- :ascii_only?,
- :bytesize,
- ]
- }
- when obj.kind_of?(Symbol)
- {
- :class => {},
- :instance => [
- :to_s,
- :size,
- :encoding,
- ]
- }
- else
- nil
- end
- methods
+ s
end
end