defly 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: