deprecator 0.0.2 → 0.0.3

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/README.md CHANGED
@@ -2,11 +2,17 @@
2
2
 
3
3
  Yet another library for dealing with code deprecation in ruby gracefully.
4
4
 
5
+ Allows you to replace behavior. For example before some important release you want to revise all deprecated code that is being called by your tests (and you have near 100% coverage, don't you?) - you can just throw in a strategy, that raises an error.
6
+
7
+ The same technique also provides for ability to make deprecation messages localized via l10n/i18n etc.
8
+
5
9
  ## Installation
6
10
 
7
11
  Add this line to your application's Gemfile:
8
12
 
13
+ ```ruby
9
14
  gem 'deprecator'
15
+ ```
10
16
 
11
17
  And then execute:
12
18
 
@@ -20,7 +26,73 @@ Or install it yourself as:
20
26
 
21
27
  ```ruby
22
28
 
29
+ #!/usr/bin/env ruby
30
+
31
+ require 'deprecator'
32
+
33
+ class SomeClass
34
+ deprecated
35
+
36
+ def method1
37
+ deprecated
38
+ end
39
+
40
+ def method2
41
+ if true
42
+ deprecated "this is deprecated when true is true"
43
+ end
44
+ end
45
+
46
+ deprecated_method
47
+ def method3
48
+ end
49
+
50
+ deprecated_method :method4, "%{method} is no longer here, use some other method!"
51
+ deprecated_method [:method5, :method6], "%{method} is no longer here, use some other method!"
52
+ end
53
+
54
+ obj = SomeClass.new # outputs to stderr: [DEPRECATED] deprecated class SomeClass instantiated at /Users/vasfed/work/deprecator/examples/example.rb:26:in `new'
55
+ obj.method1 # [DEPRECATED] method1 is deprecated!
56
+ obj.method2 # [DEPRECATED] this is deprecated when true is true
57
+ obj.method3 # [DEPRECATED] method method3 is deprecated. Called from /Users/vasfed/work/deprecator/examples/example.rb:28:in `<top (required)>'
58
+ obj.method4 # [DEPRECATED] method4 is no longer here, use some other method!
59
+ obj.method6 # [DEPRECATED] method6 is no longer here, use some other method!
60
+
61
+ ```
62
+
63
+ changing strategies:
64
+
65
+ ```ruby
66
+
67
+ Deprecator.strategy = :raise # included: warning(default), raise, raiseHard
68
+
69
+ class SomeClass
70
+ deprecated "some reason"
71
+ def initialize
72
+ puts "SomeClass#initialize called"
73
+ end
74
+ end
75
+
76
+ begin
77
+ SomeClass.new
78
+ rescue Deprecator::Deprecated => e
79
+ puts "caught exception #{e.class}: #{e}"
80
+ end
81
+
82
+
83
+ class CustomStrategy < Deprecator::Strategy::Base
84
+ def object_found *args
85
+ puts "Deprecated object created."
86
+ end
87
+ end
88
+
89
+ Deprecator.strategy = CustomStrategy
90
+ SomeClass.new
23
91
 
92
+ # outputs:
93
+ # caught exception Deprecator::DeprecatedObjectCreated: some reason
94
+ # Deprecated object created.
95
+ # SomeClass#initialize called
24
96
 
25
97
  ```
26
98
 
data/Rakefile CHANGED
@@ -13,3 +13,7 @@ end
13
13
  # task :test => :compile
14
14
 
15
15
  task :default => :test
16
+
17
+ task :run_example do
18
+ load File.expand_path('../examples/example.rb', __FILE__)
19
+ end
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'deprecator'
4
+
5
+ class SomeClass
6
+ deprecated
7
+
8
+ def method1
9
+ deprecated
10
+ end
11
+
12
+ def method2
13
+ if true
14
+ deprecated "this is deprecated when true is true"
15
+ end
16
+ end
17
+
18
+ deprecated_method
19
+ def method3
20
+ end
21
+
22
+ deprecated_method :method4, "%{method} is no longer here, use some other method!"
23
+ deprecated_method [:method5, :method6], "%{method} is no longer here, use some other method!"
24
+ end
25
+
26
+ obj = SomeClass.new # outputs to stderr: [DEPRECATED] deprecated class SomeClass instantiated at /Users/vasfed/work/deprecator/examples/example.rb:26:in `new'
27
+ obj.method1 # [DEPRECATED] method1 is deprecated!
28
+ obj.method2 # [DEPRECATED] this is deprecated when true is true
29
+ obj.method3 # [DEPRECATED] method method3 is deprecated. Called from /Users/vasfed/work/deprecator/examples/example.rb:28:in `<top (required)>'
30
+ obj.method4 # [DEPRECATED] method4 is no longer here, use some other method!
31
+ obj.method6 # [DEPRECATED] method6 is no longer here, use some other method!
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'deprecator'
4
+
5
+ Deprecator.strategy = :raise # included: warning(default), raise, raiseHard
6
+
7
+ class SomeClass
8
+ deprecated "some reason"
9
+ def initialize
10
+ puts "SomeClass#initialize called"
11
+ end
12
+ end
13
+
14
+ begin
15
+ SomeClass.new
16
+ rescue Deprecator::Deprecated => e
17
+ puts "caught exception #{e.class}: #{e}"
18
+ end
19
+
20
+
21
+ class CustomStrategy < Deprecator::Strategy::Base
22
+ def object_found *args
23
+ puts "Deprecated object created."
24
+ end
25
+ end
26
+
27
+ Deprecator.strategy = CustomStrategy
28
+ SomeClass.new
29
+
30
+ # outputs:
31
+ # caught exception Deprecator::DeprecatedObjectCreated: some reason
32
+ # Deprecated object created.
33
+ # SomeClass#initialize called
@@ -4,28 +4,48 @@ require 'is_a'
4
4
 
5
5
  module Deprecator
6
6
 
7
+ class UnknownStrategy < ArgumentError; end
8
+
9
+ class Deprecated < RuntimeError; end
10
+ class DeprecatedMethodCalled < Deprecated; end
11
+ class DeprecatedObjectCreated < Deprecated; end
12
+
13
+ class CodeError < RuntimeError; end
14
+ class NotImplemented < CodeError; end
15
+ class Fixme < CodeError; end
16
+ class Todo < CodeError; end
17
+
18
+
19
+
20
+
7
21
  class DeprecatedClass
8
22
  def self.inherited cls
9
- cls.extend(Deprecated)
23
+ ::Deprecator.strategy.class_found(cls, caller_line)
24
+ # cls.extend(Deprecated::ClassMethods)
25
+ # cls.send :include, Deprecated::InstanceMethods
10
26
  end
11
27
  end
12
28
 
13
- module Deprecated
29
+ module DeprecatorModule
14
30
  def self.included cls
15
31
  cls.extend self
16
32
  end
17
33
 
18
34
  def self.extended cls
19
35
  ::Deprecator.strategy.class_found(cls, caller_line)
20
- cls.send :include, InstanceMethods
36
+ # cls.send :include, InstanceMethods
37
+ # cls.extend ClassMethods
21
38
  end
22
39
 
23
- module InstanceMethods
24
- # SMELL: initialize in module is no good, but in this case may help for some cases
25
- def initialize *args
26
- ::Deprecator.strategy.object_found(self, caller_line)
27
- end
28
- end
40
+ # module ClassMethods
41
+ # end
42
+
43
+ # module InstanceMethods
44
+ # # SMELL: initialize in module is no good, but in this case may help for some cases
45
+ # def initialize *args
46
+ # ::Deprecator.strategy.object_found(self, caller_line)
47
+ # end
48
+ # end
29
49
  Class = DeprecatedClass
30
50
  end
31
51
 
@@ -42,17 +62,21 @@ module Deprecator
42
62
  @method_added_stack.push(m)
43
63
  end
44
64
 
65
+ @skip_next_method_added_addition = true
45
66
  define_singleton_method(:method_added, ->(name){
46
67
  return if name == :method_added
47
68
  super(name)
48
69
  old = @method_added_stack.pop
49
70
  if old
71
+ @skip_next_method_added_addition = true
50
72
  define_singleton_method(:method_added, old)
73
+ remove_instance_variable :@skip_next_method_added_addition
51
74
  else
52
75
  class <<self; remove_method(:method_added); end
53
76
  end
54
77
  blk.call(name)
55
78
  })
79
+ remove_instance_variable :@skip_next_method_added_addition
56
80
  end
57
81
 
58
82
  def deprecated_method name=nil, reason=nil, &blk
@@ -78,8 +102,6 @@ module Deprecator
78
102
 
79
103
  DefaultStrategy = Strategy::Warning
80
104
 
81
- class UnknownStrategy < ArgumentError; end
82
- class NotImplemented < RuntimeError; end
83
105
 
84
106
  @@strategy = nil
85
107
  def self.strategy
@@ -22,5 +22,5 @@ module Kernel
22
22
  alias NOT_IMPLEMENTED not_implemented
23
23
  end
24
24
 
25
- DEPRECATED = Deprecator::Deprecated
25
+ DEPRECATED = Deprecator::DeprecatorModule
26
26
  Deprecated = DEPRECATED unless Object.const_defined?(:Deprecated)
@@ -1,15 +1,38 @@
1
1
  module Deprecator
2
2
  module Strategy
3
3
 
4
-
5
4
  class Base
6
- def class_found o, where=nil, reason=nil, args=nil
7
- # msg(if reason
8
- # reason.gsub(/%{cls}/, o)
9
- # else
10
- # "#{o} is deprecated!"
11
- # end, where)
5
+ #on class/module definition/extenting with deprecater or deprecate statement
6
+ def class_found cls, where=nil, reason=nil, args=nil
7
+ this = self
8
+ cls.send(:define_method, :initialize){|*args|
9
+ ::Deprecator.strategy.object_found(cls, self, reason, caller_line, where)
10
+ }
11
+
12
+ cls.send(:define_singleton_method, :method_added, ->(name){
13
+ super(name)
14
+ if name == :initialize && !@skip_next_initialize_addition
15
+ meth = instance_method(name)
16
+ @skip_next_initialize_addition = true
17
+ define_method(name){|*args|
18
+ ::Deprecator.strategy.object_found(cls, self, reason, caller_line, where)
19
+ meth.bind(self).call(*args)
20
+ }
21
+ remove_instance_variable :@skip_next_initialize_addition
22
+ end
23
+ })
24
+ cls.send(:define_singleton_method, :singleton_method_added, ->(name){
25
+ #guard for self?
26
+ if name == :method_added && !@skip_next_method_added_addition
27
+ warn "[WARNING] when you replace method_added for deprecated class - you can no longer autotrack its object creation, use deprecation of initialize method."
28
+ end
29
+ })
30
+ end
31
+
32
+ # on deprecated class initialize
33
+ def object_found cls, object, reason, where, deprecated_at
12
34
  end
35
+ # on method definition
13
36
  def method_found cls,name, reason, where=nil
14
37
  this = self
15
38
  unless cls.method_defined?(name) # also we may place stubs there for existing methods in other strategies
@@ -24,6 +47,8 @@ module Deprecator
24
47
  }
25
48
  end
26
49
  end
50
+ def method_called cls,name,reason=nil,where,defined_at; end
51
+ def deprecated reason=nil, where=caller_line, args=nil; end
27
52
  def fixme! msg, where, args; end
28
53
  def todo! msg, where, args; end
29
54
  def not_implemented msg, where, args
@@ -31,18 +56,20 @@ module Deprecator
31
56
  end
32
57
  end
33
58
 
59
+
60
+
34
61
  class Warning < Base
35
62
  def msg msg, where=nil
36
- warn "[DEPRECATED] #{msg}"
63
+ warn "[DEPRECATED] #{msg}".gsub('%{where}', where)
37
64
  end
38
65
 
39
- def object_found o, where=nil, reason=nil # deprecated class initialize
40
- msg "deprecated class #{o.class} instantiated", where
66
+ def object_found cls, object, reason, where, deprecated_at # deprecated class initialize
67
+ msg "deprecated class #{cls} instantiated at %{where}", where
41
68
  end
42
69
 
43
- # this is not entry point
44
70
  def method_called cls,name,reason=nil,where,defined_at
45
- msg "method #{name} is deprecated. Called from #{caller_line}"
71
+ reason ||= "method %{method} is deprecated. Called from %{where}"
72
+ msg reason.gsub('%{method}', name.to_s), where
46
73
  end
47
74
 
48
75
  def deprecated reason=nil, where=caller_line, args=nil
@@ -55,5 +82,45 @@ module Deprecator
55
82
  end
56
83
 
57
84
 
85
+
86
+ class Raise < Base
87
+ def object_found cls, object, reason, where, deprecated_at # deprecated class initialize
88
+ raise DeprecatedObjectCreated, reason || "deprecated"
89
+ end
90
+
91
+ def method_called cls,name,reason=nil,where,defined_at
92
+ reason ||= "method %{method} is deprecated."
93
+ raise DeprecatedMethodCalled, (reason || "deprecated").gsub('%{method}', name.to_s)
94
+ end
95
+
96
+ def deprecated reason=nil, where=caller_line, args=nil
97
+ where =~ /in `(.+)'$/
98
+ method_name = $1 || '<unknown>'
99
+ reason ||= "%{method} is deprecated!"
100
+ reason.gsub!('%{method}', method_name)
101
+ raise Deprecated, reason
102
+ end
103
+ end
104
+
105
+
106
+
107
+ class RaiseHard < Raise
108
+ def class_found cls, where=nil, reason=nil, args=nil
109
+ raise Deprecated, "#{cls} is deprecated"
110
+ end
111
+
112
+ def method_found cls,name, reason, where=nil
113
+ raise Deprecated, "#{cls}##{name} is deprecated"
114
+ end
115
+
116
+ def fixme! msg, where, args;
117
+ raise Deprecator::Fixme, msg
118
+ end
119
+
120
+ def todo! msg, where, args
121
+ raise Deprecator::Todo, msg
122
+ end
123
+ end
124
+
58
125
  end
59
126
  end
@@ -1,3 +1,3 @@
1
1
  module Deprecator
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -46,7 +46,7 @@ describe Deprecator do
46
46
 
47
47
  context "methods" do
48
48
  before{
49
- subject.strategy = :warning
49
+ subject.strategy = :base
50
50
  }
51
51
  it "simple" do
52
52
  subject.strategy.should_receive(:deprecated).with("reason", duck_type(:to_s), [])
@@ -73,6 +73,34 @@ describe Deprecator do
73
73
  end
74
74
 
75
75
  context "strategy" do
76
+ context "also installs hooks for class instantiation" do
77
+ before{ subject.strategy = :base }
78
+ it "without a reason passed" do
79
+ cls = Class.new(DEPRECATED::Class)
80
+ subject.strategy.should_receive(:object_found).with(cls, kind_of(cls), nil, /#{Regexp.escape __FILE__}:#{__LINE__+1}/, /#{Regexp.escape __FILE__}:#{__LINE__-1}/)
81
+ cls.new
82
+ end
83
+
84
+ it "with reason passed" do
85
+ cls = Class.new{ deprecated "reason" }
86
+ subject.strategy.should_receive(:object_found).with(cls, kind_of(cls), "reason", /#{Regexp.escape __FILE__}:#{__LINE__+1}/, /#{Regexp.escape __FILE__}:#{__LINE__-1}/)
87
+ cls.new
88
+ end
89
+
90
+ it "and guards for initialize method" do
91
+ cls = Class.new{
92
+ deprecated "reason"
93
+ # def self.method_added(name); puts "method added #{name}"; end
94
+ def initialize
95
+ self.class.initialize_called
96
+ end
97
+ }
98
+ cls.should_receive(:initialize_called).once
99
+ subject.strategy.should_receive(:object_found).with(cls, kind_of(cls), "reason", /#{Regexp.escape __FILE__}:#{__LINE__+1}/, /#{Regexp.escape __FILE__}:#{__LINE__-7}/)
100
+ cls.new
101
+ end
102
+ end
103
+
76
104
  context "set" do
77
105
  it "via object" do
78
106
  obj = Object.new
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deprecator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -89,6 +89,8 @@ files:
89
89
  - README.md
90
90
  - Rakefile
91
91
  - deprecator.gemspec
92
+ - examples/example.rb
93
+ - examples/example2.rb
92
94
  - lib/deprecator.rb
93
95
  - lib/deprecator/core_ext.rb
94
96
  - lib/deprecator/strategy.rb
@@ -116,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
118
  version: '0'
117
119
  segments:
118
120
  - 0
119
- hash: -2851817988265802731
121
+ hash: 2302177472746095841
120
122
  requirements: []
121
123
  rubyforge_project:
122
124
  rubygems_version: 1.8.24