cutter 0.6.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,14 +1,21 @@
1
- = cutter
1
+ h1. Cutter
2
+
3
+ Two-methods-gem I use a lot for simple debugging & performance measuring purposes.
2
4
 
3
- For now it is two-methods-gem I use a lot for simple debugging & performance measuring purposes.
4
5
  Include it into Gemfile:
5
- gem 'cutter'
6
6
 
7
- Methods are:
7
+ <pre>
8
+ <code>
9
+ gem 'cutter'
10
+ </code>
11
+ </pre>
8
12
 
9
- ==I) #inspect!
13
+ h2. I) #inspect!
10
14
 
11
15
  Insert #inspect! method into any of your methods:
16
+
17
+ <pre>
18
+ <code>
12
19
  def your_method *your_args
13
20
  inspect! {} # this string exactly!
14
21
  ...
@@ -19,9 +26,13 @@ Insert #inspect! method into any of your methods:
19
26
  method `your_method'
20
27
  variables:
21
28
  args: [1, "foo", :bar]
29
+ </code>
30
+ </pre>
22
31
 
23
32
  or in more rigorous way:
24
33
 
34
+ <pre>
35
+ <code>
25
36
  def your_another_method(first, second, third, &block)
26
37
  inspect!(binding)
27
38
  end
@@ -34,12 +45,15 @@ or in more rigorous way:
34
45
  second: "foo"
35
46
  third: :bar
36
47
  block:
37
-
48
+ </code>
49
+ </pre>
38
50
 
39
51
  Gives simple but nice trace for inspection: method's name and args that were passed to method
40
52
 
41
53
  With :inspect => true we have self#inspect of class to which method belongs to:
42
54
 
55
+ <pre>
56
+ <code>
43
57
  def method_self_inspect
44
58
  ...
45
59
  inspect!(:inspect => true) {}
@@ -55,9 +69,13 @@ With :inspect => true we have self#inspect of class to which method belongs to:
55
69
  block:
56
70
  self inspection:
57
71
  #<SelfInspectDemo:0x82be488 @variable="I'm variable">
72
+ </code>
73
+ </pre>
58
74
 
59
75
  And finally :level => N gives caller methods chain (N + 1 caller methods):
60
76
 
77
+ <pre>
78
+ <code>
61
79
  def method_caller_chain
62
80
  ...
63
81
  inspect!(:level => 2)
@@ -75,59 +93,97 @@ And finally :level => N gives caller methods chain (N + 1 caller methods):
75
93
  /home/stanislaw/_work_/gems/cutter/spec/inspection/demo_spec.rb:33:in `method_caller_chain'
76
94
  /home/stanislaw/_work_/gems/cutter/spec/inspection/demo_spec.rb:40:in `block (3 levels) in <top (required)>'
77
95
  /home/stanislaw/.rvm/gems/ruby-1.9.2-p180@310/gems/rspec-core-2.6.4/lib/rspec/core/example.rb:48:in `instance_eval'
96
+ </code>
97
+ </pre>
78
98
 
79
99
  If you want all #inspect! methods fall silent at once, use
80
- Cutter::Inspection.quiet!
100
+ @Cutter::Inspection.quiet!@
81
101
  To make them sound again do
82
- Cutter::Inspection.loud!
102
+ @Cutter::Inspection.loud!@
83
103
 
84
104
  You can clone it and try
85
105
 
86
- bundle exec rspec spec/inspection/demo_spec.rb
106
+ @bundle exec rspec spec/inspection/demo_spec.rb@
87
107
 
88
108
  Very! Very simple!
89
109
 
90
- ==II) #stamper
91
- def your_method
92
- stamper("testing pieces of code") do
93
- piece_of_code #1
94
- stamp("piece #1 performed!")
95
- piece_of_code #2
96
- stamp("piece #2 performed!")
97
- pirce_of_code #3
98
- end
99
- end
100
-
101
- your_method =>
102
- ~ testing pieces of code
103
- ~ testing: start
104
- ~ testing: piece #1 performed!, 10ms
105
- ~ testing: piece #2 performed!, 231ms
106
- ~ testing: end (247ms)
107
-
108
-
109
- or simply:
110
- def test_method
111
- stamper {
112
- piece of code
113
- }
114
- end
110
+ h2. II) #stamper
111
+
112
+ <pre>
113
+ <code>
114
+ Stamper.scope :stan => "testing test_method" do |stan|
115
+ stan.msg _1: 'stamp1'
116
+ stan.msg _2: 'stamp2'
117
+ stan.msg _3: 'stamp3'
118
+ end
119
+
120
+ Stamper.scope :hello => "testing hello part" do |stan|
121
+ stan.msg _1: 'hello stan'
122
+ stan.msg _2: 'nice to see you'
123
+ end
124
+
125
+ v = 32
126
+
127
+ stamper :stan do |s|
128
+ s.stamp
129
+ s.stamp :_1
130
+ sleep 0.1
131
+ s.stamp :_2
132
+ s.stamp :hello_world
133
+ stamper :hello do |s|
134
+ s.stamp :_1
135
+ sleep 0.1
136
+ s.stamp :_2
137
+ end
138
+ sleep 0.1
139
+ s.stamp "hello world: #{v}" # access var before block
140
+ s.stamp :_3
141
+ sleep 0.1
142
+ end
143
+
144
+ =>
145
+
146
+ ------------------------------
147
+ ~ START "testing test_method"
148
+ ~ stamp: 0 ms
149
+ ~ stamp: 0 ms stamp1
150
+ ~ stamp: 101 ms stamp2
151
+ ~ stamp: 101 ms Hello world
152
+ ------------------------------
153
+ ~ START "testing hello part"
154
+ ~ stamp: 0 ms hello stan
155
+ ~ stamp: 101 ms nice to see you
156
+ ~ END "testing hello part"
157
+ [101ms]
158
+ ------------------------------
159
+ ~ stamp: 305 ms Hello world: 32
160
+ ~ stamp: 305 ms stamp3
161
+ ~ END "testing test_method"
162
+ [406ms]
163
+ ------------------------------
164
+ </code>
165
+ </pre>
166
+
167
+ or simply:
168
+ <pre>
169
+ <code>
170
+ def test_method
171
+ stamper {
172
+ piece of code
173
+ }
174
+ end
175
+ </code>
176
+ </pre>
115
177
 
116
178
  Acts as self.benchmark{} (in Rails) or Benchmark.measure{} (common Ruby) but with stamps in any position in block executed.
117
179
  It is much simpler to write it quickly than all these Measure-dos.
118
180
 
119
- == Contributing to cutter
120
-
121
- * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
122
- * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
123
- * Fork the project
124
- * Start a feature/bugfix branch
125
- * Commit and push until you are happy with your contribution
126
- * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
127
- * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
181
+ h2. Contributors
182
+
183
+ * Stanislaw Pankevich
184
+ * Kristian Mandrup
128
185
 
129
- == Copyright
186
+ h2. Copyright
130
187
 
131
- Copyright (c) 2011 Stanislaw Pankevich. See LICENSE.txt for
132
- further details.
188
+ Copyright (c) 2011 Stanislaw Pankevich
133
189
 
@@ -1,4 +1,7 @@
1
1
  require 'cutter/array'
2
2
  require 'cutter/railtie' if defined?(Rails)
3
+
4
+ require 'cutter/colored_outputs'
3
5
  require 'cutter/stamper'
4
6
  require 'cutter/inspection'
7
+
@@ -0,0 +1,61 @@
1
+ require 'colorize'
2
+ class Object
3
+
4
+ def line sp = ""
5
+ log_coloured sp, "------------------------------", color(:line)
6
+ end
7
+
8
+
9
+ def log_coloured sp, msg, color = :default
10
+ message = sp + msg
11
+ message = color != :default ? message.send(color) : message
12
+ puts message
13
+ end
14
+ end
15
+
16
+ module Cutter
17
+ module ColoredOutputs
18
+ module ClassMethods
19
+ def turn_colors state = :on
20
+ @colors_state = state
21
+ end
22
+
23
+ def colors?
24
+ @colors_state ||= :on
25
+ @colors_state == :on
26
+ end
27
+
28
+ def colors &block
29
+ yield colors_config
30
+ end
31
+
32
+ def colors_config
33
+ @colors ||= {:line => :blue,
34
+ :time => :light_blue,
35
+
36
+ # Colors for #inspect!
37
+ #:called_from => :light_magenta,
38
+ #:class_name => :red,
39
+ #:method => :blue,
40
+ #:method_name => :green,
41
+ #:lv => :blue,
42
+ #:lv_names => :magenta,
43
+ #:lv_values => :light_red,
44
+ #:iv => :cyan,
45
+ #:iv_names => :light_cyan,
46
+ #:iv_values => :light_blue,
47
+ #:self_inspection => :red,
48
+ #:self_inspection_trace => :blue,
49
+ #:caller_methods => :light_cyan,
50
+ #:caller_method => :green
51
+ }
52
+ end
53
+ end
54
+
55
+ extend ClassMethods
56
+
57
+ def self.included(base)
58
+ base.extend ClassMethods
59
+ end
60
+ end
61
+ end
@@ -24,6 +24,15 @@ class Object
24
24
  def inspect! *options, &block
25
25
  return true if Cutter::Inspection.quiet?
26
26
 
27
+ def __colors
28
+ Cutter::ColoredOutputs.colors_config
29
+ end
30
+
31
+ def to_cs obj
32
+ color = __colors[obj] || :default
33
+ color != :default ? to_s.send(color) : to_s
34
+ end
35
+
27
36
  # Getting binding
28
37
  _binding = options.first if options.first.class == Binding
29
38
  raise ArgumentError, "Try inspect(binding) or inspect! {}", caller if (!block_given? && !_binding)
@@ -41,40 +50,45 @@ class Object
41
50
  self_inspection = eval('self.inspect', _binding) if options[:inspect]
42
51
 
43
52
  # Basic info
44
- puts %|\nmethod: `#{eval('__method__', _binding)}' #{'(maximal tracing)' if max}|
45
- puts %| called from class: #{eval('self.class', _binding)}|
53
+ method_name = eval('__method__', _binding)
54
+ class_name = eval('self.class', _binding)
55
+
56
+ puts "\n%s `%s' %s" % ['method:'.to_cs(:method), method_name.to_cs(:method_name), ('(maximal tracing)' if max)]
57
+ puts " %s %s" % ['called from class:'.to_cs(:called_from), class_name.to_cs(:class_name)]
46
58
 
59
+ # Local Variables
47
60
  lvb = eval('local_variables',_binding)
48
- puts %| local_variables: #{"[]" if lvb.empty?}|
61
+ puts " %s %s" % ['local_variables:'.to_cs(:lv), ("[]" if lvb.empty?)]
49
62
 
50
63
  lvb.map do |lv|
51
64
  local_variable = eval(lv.to_s, _binding)
52
65
  local_variable = (max ? local_variable.inspect : local_variable.to_real_string)
53
66
 
54
- puts %| #{lv}: #{local_variable}|
67
+ puts " %s: %s" % [lv.to_cs(:lv_names), local_variable.to_cs(:lv_values)]
55
68
  end if lvb
56
69
 
57
70
  ivb = eval('instance_variables',_binding)
58
- puts %| instance_variables: #{"[]" if ivb.empty?}|
59
71
 
60
- ivb.map do |lv|
61
- instance_variable = eval(lv.to_s, _binding)
72
+ puts " %s %s" % ["instance_variables:".to_cs(:iv), ("[]" if ivb.empty?)]
73
+
74
+ ivb.map do |iv|
75
+ instance_variable = eval(iv.to_s, _binding)
62
76
  instance_variable = (max ? instance_variable.inspect : instance_variable.to_real_string)
63
77
 
64
- puts %| #{lv}: #{instance_variable}|
78
+ puts " %s: %s" % [iv.to_cs(:iv_names), instance_variable.to_cs(:iv_values)]
65
79
  end if ivb
66
80
 
67
81
  # Self inspection
68
82
  begin
69
- puts %| self inspection:|
70
- puts %| #{self_inspection}|
83
+ puts " self inspection:".to_cs(:self_inspection)
84
+ puts " %s" % self_inspection.to_cs(:self_inspection_trace)
71
85
  end if self_inspection
72
86
 
73
87
  # Caller methods chain
74
88
  begin
75
- puts %| caller methods: |
89
+ puts " caller methods: ".to_cs(:caller_methods)
76
90
  0.upto(level).each {|index|
77
- puts %| #{_caller[index]}|
91
+ puts " %s" % _caller[index].to_cs(:caller_method)
78
92
  }
79
93
  end if level
80
94
 
@@ -1,32 +1,75 @@
1
1
  require 'set'
2
+ require 'active_support/core_ext/string/inflections.rb'
2
3
 
3
4
  class Object
4
5
  def time_now
5
6
  Time.now.strftime("%s%L").to_i
6
7
  end
7
8
 
8
- def stamper name, &block
9
+ def stamper name = nil, &block
10
+
11
+ def log_time sp, msg
12
+ log_coloured sp, msg, color(:time)
13
+ end
14
+
15
+ def color type
16
+ Stamper.colors_config[type] if Stamper.colors?
17
+ end
18
+
19
+ return if Stamper.off?
9
20
  scope = Stamper[name] || Stamper[:default]
21
+ scope.indent = Stamper.last ? Stamper.last.indent + 1 : 0
22
+ Stamper.push scope
23
+
10
24
  msg = 'no msg'
11
25
  if scope
12
26
  message = scope.label.values.first
13
27
  end
14
-
15
- puts("~ #{message}")
16
- puts("~ testing: start")
28
+ spaces = " " * scope.indent
29
+ line spaces
30
+ log_coloured spaces, "~ START " << "#{message}"
17
31
  scope.time_initial = time_now
18
32
  yield scope
33
+ scope.indent -= 1 if scope.indent > 0
34
+ Stamper.pop
19
35
  time_passed = time_now - scope.time_initial
20
- puts("~ testing: end (#{time_passed}ms)")
36
+ log_coloured spaces, "~ END " << "#{message}"
37
+ log_time spaces, "[#{time_passed}ms]"
38
+ line spaces
21
39
  end
22
40
  end
23
41
 
24
42
  class Stamper
25
- attr_reader :label
43
+ attr_reader :label
26
44
  attr_accessor :time_initial
45
+ attr_writer :indent
46
+
47
+ include Cutter::ColoredOutputs
27
48
 
28
49
  def initialize label
29
50
  @label = label
51
+ @indent = 0
52
+ end
53
+
54
+ def self.turn state = :on
55
+ @state = state
56
+ end
57
+
58
+ def self.on?
59
+ @state ||= :on
60
+ @state == :on
61
+ end
62
+
63
+ def self.off?
64
+ !on?
65
+ end
66
+
67
+ def indent
68
+ @indent ||= 0
69
+ end
70
+
71
+ def nindent
72
+ @indent +1
30
73
  end
31
74
 
32
75
  def msg label
@@ -44,30 +87,53 @@ class Stamper
44
87
  end
45
88
 
46
89
  def stamp lbl = nil
47
- message = messages[lbl] || lbl
90
+ return if Stamper.off?
91
+ message = messages[lbl] || lbl.to_s.humanize
48
92
  time_passed = time_now - time_initial
93
+ print " " * nindent
49
94
  printf("~ stamp: %7d ms #{message}\n", time_passed)
50
95
  end
51
96
 
52
97
  module ClassMethods
98
+
53
99
  def scope label, &block
54
100
  raise ArgumentError, "Must have hash, was: #{label}" if !label.kind_of? Hash
55
101
  raise ArgumentError, "Must have block" if !block
56
102
  stamper = Stamper.new(label)
57
103
  stampers[label.keys.first] = stamper
58
104
  yield stamper
105
+ stamper_stack.pop
59
106
  stamper
60
107
  end
61
108
 
109
+ def last
110
+ stamper_stack.last
111
+ end
112
+
113
+ def push stamper
114
+ stamper_stack.push stamper
115
+ end
116
+
117
+ def pop
118
+ stamper_stack.pop
119
+ end
120
+
62
121
  def [] key
63
122
  stampers[key]
64
123
  end
65
124
 
66
125
  protected
67
126
 
127
+ def stamper_stack
128
+ @stamper_stack ||= []
129
+ end
130
+
68
131
  def stampers
69
132
  @stampers ||= {}
70
133
  end
71
134
  end
72
135
  extend ClassMethods
73
136
  end
137
+
138
+ Stamper.scope :default => nil do |default|
139
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: cutter
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.6.0
5
+ version: 0.8.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - stanislaw
@@ -10,75 +10,64 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-08-07 00:00:00 +03:00
13
+ date: 2011-08-08 00:00:00 +03:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
- name: rspec
17
+ name: activesupport
18
18
  requirement: &id001 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: "0"
23
+ version: 2.3.5
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: *id001
27
27
  - !ruby/object:Gem::Dependency
28
- name: rspec-rails
28
+ name: colorize
29
29
  requirement: &id002 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: "0"
34
+ version: "0.5"
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: *id002
38
- - !ruby/object:Gem::Dependency
39
- name: shoulda
40
- requirement: &id003 !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ">="
44
- - !ruby/object:Gem::Version
45
- version: "0"
46
- type: :runtime
47
- prerelease: false
48
- version_requirements: *id003
49
38
  - !ruby/object:Gem::Dependency
50
39
  name: bundler
51
- requirement: &id004 !ruby/object:Gem::Requirement
40
+ requirement: &id003 !ruby/object:Gem::Requirement
52
41
  none: false
53
42
  requirements:
54
43
  - - ~>
55
44
  - !ruby/object:Gem::Version
56
45
  version: 1.0.0
57
- type: :runtime
46
+ type: :development
58
47
  prerelease: false
59
- version_requirements: *id004
48
+ version_requirements: *id003
60
49
  - !ruby/object:Gem::Dependency
61
50
  name: jeweler
62
- requirement: &id005 !ruby/object:Gem::Requirement
51
+ requirement: &id004 !ruby/object:Gem::Requirement
63
52
  none: false
64
53
  requirements:
65
54
  - - ~>
66
55
  - !ruby/object:Gem::Version
67
56
  version: 1.6.2
68
- type: :runtime
57
+ type: :development
69
58
  prerelease: false
70
- version_requirements: *id005
59
+ version_requirements: *id004
71
60
  - !ruby/object:Gem::Dependency
72
61
  name: rcov
73
- requirement: &id006 !ruby/object:Gem::Requirement
62
+ requirement: &id005 !ruby/object:Gem::Requirement
74
63
  none: false
75
64
  requirements:
76
65
  - - ">="
77
66
  - !ruby/object:Gem::Version
78
67
  version: "0"
79
- type: :runtime
68
+ type: :development
80
69
  prerelease: false
81
- version_requirements: *id006
70
+ version_requirements: *id005
82
71
  description: longer description of your gem
83
72
  email: s.pankevich@gmail.com
84
73
  executables: []
@@ -87,15 +76,16 @@ extensions: []
87
76
 
88
77
  extra_rdoc_files:
89
78
  - LICENSE.txt
90
- - README.rdoc
79
+ - README.textile
91
80
  files:
92
81
  - lib/cutter.rb
93
82
  - lib/cutter/array.rb
83
+ - lib/cutter/colored_outputs.rb
94
84
  - lib/cutter/inspection.rb
95
85
  - lib/cutter/railtie.rb
96
86
  - lib/cutter/stamper.rb
97
87
  - LICENSE.txt
98
- - README.rdoc
88
+ - README.textile
99
89
  has_rdoc: true
100
90
  homepage: http://github.com/stanislaw/cutter
101
91
  licenses:
@@ -110,7 +100,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
110
100
  requirements:
111
101
  - - ">="
112
102
  - !ruby/object:Gem::Version
113
- hash: 1041591087
103
+ hash: 800208499
114
104
  segments:
115
105
  - 0
116
106
  version: "0"