defly 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile CHANGED
@@ -3,6 +3,8 @@ source "http://rubygems.org"
3
3
  # Example:
4
4
  # gem "activesupport", ">= 2.3.5"
5
5
 
6
+ gem "rib"
7
+
6
8
  # Add dependencies to develop your gem here.
7
9
  # Include everything needed to run rake, tests, features, etc.
8
10
  group :development do
data/Gemfile.lock CHANGED
@@ -8,6 +8,7 @@ GEM
8
8
  rake
9
9
  rake (0.9.2)
10
10
  rcov (0.9.9)
11
+ rib (0.9.2)
11
12
  shoulda (2.11.3)
12
13
 
13
14
  PLATFORMS
@@ -17,4 +18,5 @@ DEPENDENCIES
17
18
  bundler (~> 1.0.0)
18
19
  jeweler (~> 1.6.4)
19
20
  rcov
21
+ rib
20
22
  shoulda
data/README.md CHANGED
@@ -6,12 +6,19 @@ A ruby debugging tool. Easy way to trace function calls and variables.
6
6
 
7
7
  Just `gem install defly`.
8
8
 
9
- ## Sample Usage
9
+ ## Feature
10
+ * Trace method calls: including arguments and return values
11
+ * Trace variable changes
12
+ * Showing source code when NoMethodError is thrown
13
+ * Opening a shell when a particular error occurred
14
+
15
+ ## Tracing method and instance variables
10
16
 
11
17
  ### Input
12
18
 
13
19
  ```ruby
14
20
  require 'defly'
21
+
15
22
  class Warrior
16
23
  attr_accessor :hp, :mp
17
24
 
@@ -21,7 +28,8 @@ class Warrior
21
28
  end
22
29
  end
23
30
 
24
- Warrior.new.trace([:hp, :hp=, :mp, :mp=], [:@hp, :@mp]) do |warrior|
31
+ Warrior.debug!
32
+ Warrior.new.trace([:hp, :hp=, :mp, :mp=, :sleep], [:@hp, :@mp]) do |warrior|
25
33
  warrior.hp = 10
26
34
  warrior.mp = 20
27
35
  warrior.sleep
@@ -30,30 +38,72 @@ end
30
38
 
31
39
  ### Output (Run on IRB)
32
40
 
33
- Tracing hp, hp=, mp, mp= on Warrior instance
34
- Tracing @hp, @mp on Warrior instance
35
- <<<<< Warrior#hp=(10) # (irb):12:in `block in irb_binding'
41
+ Tracing hp, hp=, mp, mp=, sleep on Warrior instance
42
+ Tracing @hp, @mp on Warrior instance
43
+ <<<<< Warrior#hp=(10) # (irb):14:in `block in irb_binding'
36
44
  @hp = 10 # undefined
37
45
  @mp = nil # undefined
38
46
  >>>>> 10
39
- <<<<< Warrior#mp=(20) # (irb):13:in `block in irb_binding'
47
+ <<<<< Warrior#mp=(20) # (irb):15:in `block in irb_binding'
40
48
  @mp = 20 # undefined
41
49
  >>>>> 20
42
- <<<<< Warrior#hp() # (irb):6:in `sleep'
43
- >>>>> 10
44
- <<<<< Warrior#hp=(20) # (irb):6:in `sleep'
45
- @hp = 20 # 10 -> 20
46
- >>>>> 20
47
- <<<<< Warrior#mp() # (irb):7:in `sleep'
48
- >>>>> 20
49
- <<<<< Warrior#mp=(22) # (irb):7:in `sleep'
50
- @mp = 22 # 20 -> 22
50
+ <<<<< Warrior#sleep() # (irb):16:in `block in irb_binding'
51
+ <<<<< Warrior#hp() # (irb):7:in `sleep'
52
+ >>>>> 10
53
+ <<<<< Warrior#hp=(20) # (irb):7:in `sleep'
54
+ @hp = 20 # 10 -> 20
55
+ >>>>> 20
56
+ <<<<< Warrior#mp() # (irb):8:in `sleep'
57
+ >>>>> 20
58
+ <<<<< Warrior#mp=(22) # (irb):8:in `sleep'
59
+ @mp = 22 # 20 -> 22
60
+ >>>>> 22
51
61
  >>>>> 22
52
- => #<Warrior:0x00000100987488 @defly_methods=[:hp, :hp=, :mp, :mp=], @defly_variables=[:@hp, :@mp], @__defly_level=0, @hp=20, @__defly={:@hp=>20, :@mp=>22}, @mp=22>
53
62
 
63
+ ## Better Error Message
64
+
65
+ ### NoMethodError
66
+
67
+ Showing the exact code and the position of the error.
68
+
69
+ ```ruby
70
+ irb(main):001:0> require 'defly'
71
+ => true
72
+ irb(main):002:0> require 'bug'
73
+ NoMethodError: undefined method `is_annoying' for "debugging":String
74
+ bug.rb:1> "debugging".<<is_annoying>>
75
+ from /Users/eggegg/bug.rb:1:in `<top (required)>'
76
+ ...
77
+ ```
78
+
79
+ ## Inspecting error
80
+
81
+ ### Input
82
+
83
+ ```ruby
84
+ class Rocket
85
+ def launch
86
+ @reason = "Bugs invasion"
87
+ raise "Engine Fail"
88
+ end
89
+ end
90
+
91
+ Rocket.debug!
92
+ rocket = Rocket.new
93
+ rocket.watch_error "Engine Fail"
94
+ rocket.launch
95
+ ```
96
+
97
+ ### Output
98
+
99
+ >>>>> Error received:
100
+ "Engine Fail"
101
+ >>>>>
102
+ #<Rocket:0(0)>> @reason
103
+ => "Bugs invasion"
104
+ #<Rocket:0(0)>>
54
105
 
55
106
  ## Copyright
56
107
 
57
108
  Copyright (c) 2011 Andrew Liu. See LICENSE.txt for
58
109
  further details.
59
-
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
data/defly.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{defly}
8
- s.version = "0.1.0"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Andrew Liu"]
12
- s.date = %q{2011-08-01}
12
+ s.date = %q{2011-08-26}
13
13
  s.description = %q{Trace methods and instance variables with ease!}
14
14
  s.email = %q{andrewliu33@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -26,7 +26,9 @@ Gem::Specification.new do |s|
26
26
  "VERSION",
27
27
  "defly.gemspec",
28
28
  "lib/defly.rb",
29
+ "lib/inspectable.rb",
29
30
  "lib/tracable.rb",
31
+ "lib/whinable.rb",
30
32
  "test/helper.rb",
31
33
  "test/test_defly.rb"
32
34
  ]
@@ -40,17 +42,20 @@ Gem::Specification.new do |s|
40
42
  s.specification_version = 3
41
43
 
42
44
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
45
+ s.add_runtime_dependency(%q<rib>, [">= 0"])
43
46
  s.add_development_dependency(%q<shoulda>, [">= 0"])
44
47
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
45
48
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
46
49
  s.add_development_dependency(%q<rcov>, [">= 0"])
47
50
  else
51
+ s.add_dependency(%q<rib>, [">= 0"])
48
52
  s.add_dependency(%q<shoulda>, [">= 0"])
49
53
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
50
54
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
51
55
  s.add_dependency(%q<rcov>, [">= 0"])
52
56
  end
53
57
  else
58
+ s.add_dependency(%q<rib>, [">= 0"])
54
59
  s.add_dependency(%q<shoulda>, [">= 0"])
55
60
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
56
61
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
data/lib/defly.rb CHANGED
@@ -1,6 +1,15 @@
1
1
  require 'tracable'
2
+ require 'whinable'
3
+ require 'inspectable'
2
4
 
3
5
  module Defly
4
6
  end
5
7
 
6
- Object.send(:include, Defly::Tracable)
8
+ class Class
9
+ def debug!
10
+ self.send(:include, Defly::Inspectable)
11
+ self.send(:include, Defly::Tracable)
12
+ end
13
+ end
14
+
15
+ NoMethodError.send(:include, Defly::Whinable)
@@ -0,0 +1,26 @@
1
+ require 'rib/core'
2
+ require 'rib/more'
3
+
4
+ module Defly
5
+ module Inspectable
6
+ def watch_error error
7
+ @__defly_watch ||= []
8
+ @__defly_watch << error
9
+ end
10
+
11
+ def raise error
12
+ @__defly_watch ||= []
13
+
14
+ if @__defly_watch.include? error.class or @__defly_watch.include? error
15
+ puts ">>>>> Error received:"
16
+ p error
17
+ puts ">>>>> "
18
+
19
+ Rib.enable_anchor do
20
+ Rib.anchor self
21
+ end
22
+ end
23
+ super
24
+ end
25
+ end
26
+ end
data/lib/tracable.rb CHANGED
@@ -10,12 +10,12 @@ module Defly
10
10
  end
11
11
 
12
12
  def trace_method!(methods)
13
- @defly_methods ||= []
13
+ @__defly_methods ||= []
14
14
 
15
15
  methods = public_methods(false) if methods.size == 0
16
16
  methods.map! {|m| m.to_sym }
17
- methods -= @defly_methods
18
- @defly_methods |= methods
17
+ methods -= @__defly_methods
18
+ @__defly_methods |= methods
19
19
 
20
20
  STDERR << "Tracing #{methods.join(', ')} on #{self.class} instance\n"
21
21
 
@@ -30,7 +30,7 @@ module Defly
30
30
  @__defly_level += 1
31
31
  result = super
32
32
  @__defly_level -= 1
33
- defly_check_var(indent) if defined? defly_check_var
33
+ __defly_check_var(indent) if defined? __defly_check_var
34
34
  STDERR << "\#{indent}>>>>> \#{result}\n"
35
35
  result
36
36
  rescue
@@ -43,37 +43,28 @@ module Defly
43
43
  end
44
44
 
45
45
  def trace_variable!(variables)
46
- @defly_variables ||= []
46
+ @__defly_variables ||= []
47
47
 
48
48
  variables = instance_variables if variables.size == 0
49
49
  variables.map! {|v| v.to_sym }
50
- variables -= @defly_variables
51
- @defly_variables |= variables
50
+ variables -= @__defly_variables
51
+ @__defly_variables |= variables
52
52
 
53
- STDERR << "Tracing #{variables.join(', ')} on #{self.class} instance\n"
53
+ STDERR << "Tracing #{variables.join(', ')} on #{self.class} instance\n"
54
54
 
55
- eigenclass.remove_method :defly_check_var_list if eigenclass.instance_methods.include? :defly_check_var_list
56
-
57
- eigenclass.class_eval <<-RUBY, __FILE__, __LINE__
58
- def defly_check_var_list
59
- [#{@defly_variables.map(&:inspect).join(', ')}]
60
- end
61
- RUBY
62
-
63
- unless eigenclass.instance_methods.include? :defly_check_var
55
+ unless eigenclass.instance_methods.include? :__defly_check_var
64
56
  eigenclass.class_eval <<-RUBY, __FILE__, __LINE__
65
- def defly_check_var(indent)
66
- @__defly ||= {}
57
+ def __defly_check_var(indent)
58
+ @__defly_varmap ||= {}
67
59
 
68
- var_list = defly_check_var_list
69
- var_list.each do |v|
60
+ @__defly_variables.each do |v|
70
61
  new_val = instance_variable_get(v)
71
- if @__defly[v]
72
- STDERR << " \#{indent}\#{v.to_s} = \#{new_val.inspect} # \#{@__defly[v].inspect} -> \#{new_val.inspect}\n" unless @__defly[v] == new_val
62
+ if @__defly_varmap[v]
63
+ STDERR << " \#{indent}\#{v.to_s} = \#{new_val.inspect} # \#{@__defly_varmap[v].inspect} -> \#{new_val.inspect}\n" unless @__defly_varmap[v] == new_val
73
64
  else
74
65
  STDERR << " \#{indent}\#{v.to_s} = \#{new_val.inspect} # undefined\n"
75
66
  end
76
- @__defly[v] = new_val
67
+ @__defly_varmap[v] = new_val
77
68
  end
78
69
  end
79
70
  RUBY
@@ -81,8 +72,8 @@ module Defly
81
72
  end
82
73
 
83
74
  def untrace!
84
- [:defly_check_var_list, :defly_check_var].concat(@defly_methods) do |m|
85
- eigenclass.remove_method(m) if eigenclass.instance_methods.include? m
75
+ [:__defly_check_var].concat(@__defly_methods).each do |m|
76
+ eigenclass.send(:remove_method, m) if eigenclass.instance_methods.include? m
86
77
  end
87
78
  end
88
79
 
@@ -90,4 +81,4 @@ module Defly
90
81
  class << self; self; end
91
82
  end
92
83
  end
93
- end
84
+ end
data/lib/whinable.rb ADDED
@@ -0,0 +1,19 @@
1
+ module Defly
2
+ module Whinable
3
+ def to_s
4
+ orig_message = super
5
+ position = backtrace[0]
6
+ message = ""
7
+ missing_method = name.to_s
8
+
9
+ unless /^\(.*\):.*/ =~ position # skipping irb
10
+ file, line, other = position.split(':')
11
+ code = IO.readlines(file)[line.to_i - 1].chomp
12
+ code.gsub!(/(#{missing_method})/, '<<\1>>')
13
+ message = "#{file.split('/')[-1]}:#{line}> #{code}"
14
+ end
15
+
16
+ "#{orig_message}\n#{message}"
17
+ end
18
+ end
19
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: defly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,23 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-08-01 00:00:00.000000000 +08:00
12
+ date: 2011-08-26 00:00:00.000000000 +08:00
13
13
  default_executable:
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rib
17
+ requirement: &2153950820 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *2153950820
15
26
  - !ruby/object:Gem::Dependency
16
27
  name: shoulda
17
- requirement: &2156047920 !ruby/object:Gem::Requirement
28
+ requirement: &2153949880 !ruby/object:Gem::Requirement
18
29
  none: false
19
30
  requirements:
20
31
  - - ! '>='
@@ -22,10 +33,10 @@ dependencies:
22
33
  version: '0'
23
34
  type: :development
24
35
  prerelease: false
25
- version_requirements: *2156047920
36
+ version_requirements: *2153949880
26
37
  - !ruby/object:Gem::Dependency
27
38
  name: bundler
28
- requirement: &2156046920 !ruby/object:Gem::Requirement
39
+ requirement: &2153948960 !ruby/object:Gem::Requirement
29
40
  none: false
30
41
  requirements:
31
42
  - - ~>
@@ -33,10 +44,10 @@ dependencies:
33
44
  version: 1.0.0
34
45
  type: :development
35
46
  prerelease: false
36
- version_requirements: *2156046920
47
+ version_requirements: *2153948960
37
48
  - !ruby/object:Gem::Dependency
38
49
  name: jeweler
39
- requirement: &2156046080 !ruby/object:Gem::Requirement
50
+ requirement: &2153947960 !ruby/object:Gem::Requirement
40
51
  none: false
41
52
  requirements:
42
53
  - - ~>
@@ -44,10 +55,10 @@ dependencies:
44
55
  version: 1.6.4
45
56
  type: :development
46
57
  prerelease: false
47
- version_requirements: *2156046080
58
+ version_requirements: *2153947960
48
59
  - !ruby/object:Gem::Dependency
49
60
  name: rcov
50
- requirement: &2156045280 !ruby/object:Gem::Requirement
61
+ requirement: &2153946880 !ruby/object:Gem::Requirement
51
62
  none: false
52
63
  requirements:
53
64
  - - ! '>='
@@ -55,7 +66,7 @@ dependencies:
55
66
  version: '0'
56
67
  type: :development
57
68
  prerelease: false
58
- version_requirements: *2156045280
69
+ version_requirements: *2153946880
59
70
  description: Trace methods and instance variables with ease!
60
71
  email: andrewliu33@gmail.com
61
72
  executables: []
@@ -73,7 +84,9 @@ files:
73
84
  - VERSION
74
85
  - defly.gemspec
75
86
  - lib/defly.rb
87
+ - lib/inspectable.rb
76
88
  - lib/tracable.rb
89
+ - lib/whinable.rb
77
90
  - test/helper.rb
78
91
  - test/test_defly.rb
79
92
  has_rdoc: true
@@ -92,7 +105,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
92
105
  version: '0'
93
106
  segments:
94
107
  - 0
95
- hash: -1991178412336427869
108
+ hash: -1635137758272325934
96
109
  required_rubygems_version: !ruby/object:Gem::Requirement
97
110
  none: false
98
111
  requirements: