module TkInspect module ClassBrowser class Base attr_accessor :tk_root attr_accessor :main_component attr_accessor :selected_class_path attr_accessor :selected_module attr_accessor :selected_method attr_accessor :browsing_method attr_accessor :class_data_sources attr_accessor :module_method_data_source def initialize @tk_root = nil @main_component = nil @selected_class_path = [] @loaded_code = {} @class_filter = nil @browsing_method = 'hierarchy' @class_data_sources = { hierarchy: ClassTreeDataSource.new, namespaces: ClassNamespaceDataSource.new }.with_indifferent_access @module_method_data_source = ModuleMethodDataSource.new end def refresh @main_component.nil? ? create_root : @main_component.regenerate end def create_root @tk_root = TkComponent::Window.new(title: "Class Browser") @main_component = RootComponent.new @main_component.class_browser = self @tk_root.place_root_component(@main_component) end def class_data_source @class_data_sources[browsing_method] end def select_class_name(class_name) self.browsing_method = 'hierarchy' class_path = class_data_source.path_for_class(class_name) select_class_path(class_path) end def show_current_path @main_component.show_current_selection end def select_class_path(class_path) self.selected_class_path = class_path module_method_data_source.selected_class = selected_class_name end def selected_class_name browsing_method.to_s == 'hierarchy' ? self.selected_class_path.last : self.selected_class_path.join('::') end def code_for_method(meth) return nil unless meth.present? class_name = selected_class_name return nil unless class_name.present? klass = Object.const_get(class_name) method = klass.instance_method(meth) file, line = method.source_location return nil unless file && line return code_for_file(file), line, file end def code_for_file(file) @loaded_code[file] || begin @loaded_code[file] = IO.read(file) @loaded_code[file] end end end end end