require "cgi" require "erb" Dir[File.join(File.dirname(__FILE__), "dt/**/*.rb")].each {|fn| require fn} # Debug toolkit. # # Allows to output debug messages from anywhere in your Rails project. # # Configure your application: # $ script/generate rails_dt # # Follow the instructions the generator gives you. # # Then anywhere in your application do a: # DT.p "Hello, world!" # DT.p "myvar", myvar # # , and see it in web output, console, and log/dt.log. module DT #:doc: # NOTE: Alphabetical order in this section. # Clear messages. def self.clear @messages = [] end # Return messages accumulated since last cleared. def self.messages @messages end # Dump a value or several values. Similar to Ruby's native p. # p "my var: " + myvar.inspect # p @myobj def self.p(*args) # Fetch caller information. c = caller.first.split(":") # Template variables. Documented in web_prefix=. hc = { :file => c[0], :line => c[1], :file_base => File.basename(c[0]), :file_rel => Pathname(c[0]).relative_path_from(Rails.root).to_s, } ##return hc args.each do |r| s = r.is_a?(String) ? r : r.inspect # NOTE: "Canonical" order of imporance: web, console, log. # To Web. if self.web_prefix pfx = ERB.new(self.web_prefix, nil, "-").result(_hash_kbinding(hc)) pcs = [] pcs << pfx pcs << CGI.escapeHTML(s).gsub("\n", "
\n") pcs << "
\n" @messages << pcs.join end # To console. if self.console_prefix pfx = ERB.new(self.console_prefix, nil, "-").result(_hash_kbinding(hc)) puts [pfx, s].join end # To log. if self.log_prefix and @log pfx = ERB.new(self.log_prefix, nil, "-").result(_hash_kbinding(hc)) @log.info [pfx, s].join end end # Be like puts -- more comfy when debugging in console. nil end # Format accumulated messages as HTML. # to_html # => Something like "". def self.to_html pcs = [] pcs << "" pcs.join end #--------------------------------------- Control stuff # Set message prefix for console. See web_prefix=. def self.console_prefix=(s) @console_prefix = s end def self.console_prefix @console_prefix end # Set logger to use. Must be a Logger. # log = Logger.new("log/my.log") def self.log=(obj) raise "Logger expected, #{obj.class} given" if not obj.is_a? Logger @log = obj end def self.log @log end # Set message prefix for log. See web_prefix=. def self.log_prefix=(s) @log_prefix = s end def self.log_prefix @log_prefix end # Set message prefix for web. Syntax is ERB. # web_prefix = '<%= file_rel %>:<%= line %> ' # # Template variables: # * file -- full path to file # * line -- line number # * file_base -- file base name # * file_rel -- file name relative to Rails application root # # By setting prefix to nil you disable respective output. # web_prefix = nil # Web output is disabled now. def self.web_prefix=(s) @web_prefix = s end def self.web_prefix @web_prefix end #--------------------------------------- # NOTE: Singletons can't be private, so mark them syntactically. # Turn hash's entries into locals and return binding. # Useful for simple templating. def self._hash_kbinding(h) #:nodoc: # NOTE: This IS important, since assignment is eval'd in this context. bnd = binding _value = nil h.each do |k, _value| ##puts "-- k-#{k.inspect} v-#{_value.inspect}" eval("#{k} = _value", bnd) end bnd end #--------------------------------------- Initialization def self._init #:nodoc: # Require Rails environment. if not defined? Rails raise "Rails environment not found. This module is meaningful in Rails only" end clear # NOTE: Don't forget to update generator/initializers/dt.rb with these. self.web_prefix = '<%= file_rel %>:<%= line %> ' self.console_prefix = "[DT <%= file_rel %>:<%= line %>] " self.log_prefix = self.console_prefix # In case of path problems @log will be nil. @log = begin Logger.new("log/dt.log") rescue Exception end end _init end # DT