├── VERSION ├── Gemfile ├── test ├── test_helper.rb └── marked_test.rb ├── Rakefile ├── LICENSE ├── marked.gemspec ├── lib └── marked.rb └── README.markdown /VERSION: -------------------------------------------------------------------------------- 1 | 1.2.3 -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | 3 | group :test do 4 | gem 'rake' 5 | gem 'jeweler' 6 | gem 'test-unit' 7 | gem 'shoulda' 8 | gem 'mocha' 9 | end 10 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit' 2 | require File.expand_path File.join(File.dirname(__FILE__), '..', 'lib', 'marked') 3 | require 'shoulda' 4 | require 'mocha' 5 | 6 | 7 | module Rails 8 | Logger = {} 9 | def self.logger 10 | Logger 11 | end 12 | end 13 | 14 | class Test::Unit::TestCase 15 | def setup 16 | Marked.stubs(:print_benchmark) 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | begin 2 | require 'jeweler' 3 | Jeweler::Tasks.new do |gem| 4 | gem.name = "marked" 5 | gem.summary = %Q{Fast debugging for Ruby. Output any objects or blocks to both Rails log and console output simultaneously} 6 | gem.description = %Q{Quick Ruby debugger. Easily print any object or string to the console and to your logs while you're working.} 7 | gem.email = "rubygems@6brand.com" 8 | gem.homepage = "http://github.com/JackDanger/marked" 9 | gem.authors = ["Jack Danger Canty"] 10 | # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings 11 | end 12 | Jeweler::GemcutterTasks.new 13 | rescue LoadError 14 | puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler" 15 | end 16 | 17 | 18 | 19 | task :default => :test 20 | 21 | require 'rake/testtask' 22 | Rake::TestTask.new(:test) do |test| 23 | test.libs << '.' 24 | test.pattern = 'test/*_test.rb' 25 | test.verbose = true 26 | end 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Jack Danger Canty 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /marked.gemspec: -------------------------------------------------------------------------------- 1 | # Generated by jeweler 2 | # DO NOT EDIT THIS FILE DIRECTLY 3 | # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' 4 | # -*- encoding: utf-8 -*- 5 | 6 | Gem::Specification.new do |s| 7 | s.name = %q{marked} 8 | s.version = "1.2.2" 9 | 10 | s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= 11 | s.authors = ["Jack Danger Canty"] 12 | s.date = %q{2011-09-14} 13 | s.description = %q{Quick Ruby debugger. Easily print any object or string to the console and to your logs while you're working.} 14 | s.email = %q{rubygems@6brand.com} 15 | s.extra_rdoc_files = [ 16 | "LICENSE", 17 | "README.markdown" 18 | ] 19 | s.files = [ 20 | "Gemfile", 21 | "LICENSE", 22 | "README.markdown", 23 | "Rakefile", 24 | "VERSION", 25 | "lib/marked.rb", 26 | "marked.gemspec", 27 | "test/marked_test.rb", 28 | "test/test_helper.rb" 29 | ] 30 | s.homepage = %q{http://github.com/JackDanger/marked} 31 | s.require_paths = ["lib"] 32 | s.rubygems_version = %q{1.4.2} 33 | s.summary = %q{Fast debugging for Ruby. Output any objects or blocks to both Rails log and console output simultaneously} 34 | 35 | if s.respond_to? :specification_version then 36 | s.specification_version = 3 37 | 38 | if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then 39 | else 40 | end 41 | else 42 | end 43 | end 44 | 45 | -------------------------------------------------------------------------------- /lib/marked.rb: -------------------------------------------------------------------------------- 1 | module Marked 2 | def mark *objects 3 | 4 | Marked.indent_out 5 | 6 | Marked.log "\nMARKED #{caller.first.split(':in ').first}" 7 | 8 | returnable = if block_given? 9 | require 'benchmark' 10 | result = nil 11 | bench = Benchmark.measure { result = yield } 12 | result 13 | else 14 | objects.last 15 | end 16 | 17 | objects.each do |object| 18 | Marked.log Marked.pad object 19 | end 20 | 21 | Marked.log Marked.pad returnable if block_given? 22 | 23 | Marked.print_benchmark bench if result 24 | 25 | Marked.rails_log " / FINISHED MARKING" 26 | 27 | returnable 28 | ensure 29 | Marked.indent_in 30 | end 31 | 32 | class << self 33 | def log object 34 | rails_log object 35 | print object 36 | end 37 | 38 | def rails_log object 39 | Rails.logger.debug object if defined?(Rails) 40 | end 41 | 42 | def print object 43 | STDOUT.puts object 44 | end 45 | 46 | def pad object 47 | " " + (" " * indent) + (object.is_a?(String) ? object : object.inspect) 48 | end 49 | 50 | def print_benchmark measurement 51 | log pad "* Executed in #{'%0.3f' % measurement.total} seconds (#{'%0.3f' % measurement.utime} cpu)\n" 52 | end 53 | 54 | def indent 55 | @indent ||= 0 56 | end 57 | 58 | def indent_out 59 | @indent = indent + 1 60 | end 61 | 62 | def indent_in 63 | @indent = indent - 1 64 | end 65 | end 66 | end 67 | 68 | class Object 69 | include Marked 70 | end 71 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | Marked 2 | = 3 | 4 |
5 | "You stroll with this intelligence 6 | in and out of fields of knowledge, getting always 7 | more marks on your preserving tablets. 8 | There is another kind of tablet, one 9 | already completed and preserved inside you. 10 | This second knowing is a fountainhead 11 | from within you, moving out" 12 | -- Rumi 13 |14 | 15 | DESCRIPTION 16 | == 17 | 18 | Ruby debugging often consists of printing out objects at various points in your code to inspect their current values. Do it fast and easy with Marked. the `mark()` method exists in global scope and always returns the values you pass into it, allowing your code to run as normal but giving you intermediate feedback. 19 | 20 | USAGE 21 | == 22 | 23 | Before: 24 | 25 | class User < ActiveRecord::Base 26 | def some_method 27 | complex_result.with_chaining( omg.I_lost_track ) 28 | end 29 | end 30 | 31 | How do you tell what the value of `complex_result` is inside this method? 32 | How do you tell if this method even ran? 33 | You write tests. Okay, but after that, if you're tracking down a bug? 34 | 35 | class User < ActiveRecord::Base 36 | def some_method 37 | complex_result.with_chaining( mark omg.I_lost_track ) 38 | end 39 | end 40 | 41 | And you'll get the value of `complex_result` printed to your console and to the Rails log (if it exists) 42 | 43 | MARKED /code/my_file:5 44 | "omg.I_lost_track contents" 45 | 46 | Can take multiple arguments, always returning the last: 47 | 48 | 49 | class User < ActiveRecord::Base 50 | def some_method 51 | mark self, 'complex result: ', complex_result 52 | end 53 | end 54 | 55 | Also handles blocks smoothly, returning the block's result as if there were no block. 56 | 57 | class User < ActiveRecord::Base 58 | def some_method 59 | mark self, 'complex result: ' do 60 | complex_result 61 | end 62 | end 63 | end 64 | 65 | 66 | 67 | INSTALL 68 | == 69 | 70 | * gem install marked 71 | 72 | 73 | Copyright 2011 [Jack Danger Canty](http://jackcanty.com). Patches welcome, forks celebrated 74 | -------------------------------------------------------------------------------- /test/marked_test.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + '/test_helper') 2 | 3 | class MarkedTest < Test::Unit::TestCase 4 | 5 | def expect_log string 6 | Marked.expects(:log).with ' ' + Marked.pad(string) 7 | end 8 | 9 | def expect_unpadded_log string 10 | Marked.expects(:log).with string 11 | Rails.logger.expects(:debug).with " / FINISHED MARKING" 12 | end 13 | 14 | 15 | context "logging" do 16 | setup { 17 | Rails.logger.expects(:debug).with "\nMARKED #{__FILE__}:24" 18 | Marked.expects(:print).with "\nMARKED #{__FILE__}:24" 19 | Rails.logger.expects(:debug).with "#{Marked.pad ' '}this should be printed" 20 | Marked.expects(:print).with "#{Marked.pad ' '}this should be printed" 21 | Rails.logger.expects(:debug).with " / FINISHED MARKING" 22 | } 23 | should "goes to two outputs" do 24 | mark "this should be printed" 25 | end 26 | end 27 | context "printing and logging a single argument" do 28 | setup { 29 | expect_unpadded_log "\nMARKED #{__FILE__}:33" 30 | expect_log "this should be printed" 31 | } 32 | should "return its argument" do 33 | assert_equal "this should be printed", mark("this should be printed") 34 | end 35 | end 36 | context "printing and logging multiple arguments" do 37 | setup { 38 | expect_unpadded_log "\nMARKED #{__FILE__}:43" 39 | expect_log "this should be printed" 40 | expect_log "this too" 41 | } 42 | should "return its last argument" do 43 | assert_equal "this too", mark("this should be printed", "this too") 44 | end 45 | end 46 | context "printing and logging non-strings" do 47 | setup { 48 | expect_unpadded_log "\nMARKED #{__FILE__}:53" 49 | expect_log({:a =>'a'}) 50 | expect_log [1, 2, 3] 51 | } 52 | should "return its last argument as object" do 53 | assert_equal [1,2,3], mark({:a => 'a'}, [1,2,3]) 54 | end 55 | end 56 | context "printing and logging blocks" do 57 | setup { 58 | @obj = {} 59 | @obj.expects(:called!).returns('returned!').once 60 | expect_unpadded_log "\nMARKED #{__FILE__}:65" 61 | expect_log "first arg" 62 | expect_log "returned!" 63 | } 64 | should "return its last argument as object" do 65 | assert_equal 'returned!', mark('first arg') { @obj.called! } 66 | end 67 | end 68 | context "#pad" do 69 | should "prepend 7 spaces" do 70 | assert_equal (" "*7)+'padme', 71 | Marked.pad('padme') 72 | end 73 | end 74 | end 75 | --------------------------------------------------------------------------------