deprecated 2.0.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,81 @@
1
+ #
2
+ # Please see the COPYING file in the source distribution for copyright information.
3
+ #
4
+
5
+ begin
6
+ require 'rubygems'
7
+ gem 'test-unit'
8
+ rescue LoadError
9
+ end
10
+
11
+ $:.unshift 'lib'
12
+ require 'rake/testtask'
13
+ require 'rake/packagetask'
14
+ require 'rake/gempackagetask'
15
+ require 'rdoc/task'
16
+ require 'deprecated'
17
+
18
+ task :default => [ :dist ]
19
+
20
+ #
21
+ # Tests
22
+ #
23
+
24
+ Rake::TestTask.new do |t|
25
+ t.libs << 'lib'
26
+ t.test_files = FileList['test/test*.rb']
27
+ t.verbose = true
28
+ end
29
+
30
+ #
31
+ # Distribution
32
+ #
33
+
34
+ task :dist => [:test, :repackage, :gem, :rdoc]
35
+ task :distclean => [:clobber_package, :clobber_rdoc]
36
+ task :clean => [:distclean]
37
+
38
+ task :to_blog => [:clobber_rdoc, :rdoc] do
39
+ sh "rm -r $git/blog/content/docs/deprecated && mv rdoc $git/blog/content/docs/deprecated"
40
+ end
41
+
42
+
43
+ #
44
+ # Documentation
45
+ #
46
+
47
+ RDoc::Task.new do |rd|
48
+ rd.rdoc_dir = "rdoc"
49
+ rd.main = "README"
50
+ rd.rdoc_files.include("README")
51
+ rd.rdoc_files.include("./lib/**/*.rb")
52
+ rd.options = %w(-a)
53
+ end
54
+
55
+ #
56
+ # Packaging
57
+ #
58
+
59
+ spec = Gem::Specification.new do |s|
60
+ s.name = "deprecated"
61
+ s.version = Deprecated::VERSION
62
+ s.author = "Erik Hollensbe"
63
+ s.email = "erik@hollensbe.org"
64
+ s.summary = "An easy way to handle deprecating and conditionally running deprecated code"
65
+ s.has_rdoc = true
66
+ s.files = Dir['Rakefile'] + Dir['lib/deprecated.rb'] + Dir['test/test_deprecated.rb']
67
+ s.test_file = "test/test_deprecated.rb"
68
+ s.rubyforge_project = 'deprecated'
69
+ end
70
+
71
+ Rake::GemPackageTask.new(spec) do |s|
72
+ end
73
+
74
+ Rake::PackageTask.new(spec.name, spec.version) do |p|
75
+ p.need_tar_gz = true
76
+ p.need_zip = true
77
+ p.package_files.include("./setup.rb")
78
+ p.package_files.include("./Rakefile")
79
+ p.package_files.include("./lib/**/*.rb")
80
+ p.package_files.include("./test/**/*")
81
+ end
@@ -1,199 +1,203 @@
1
+ class DeprecatedError < StandardError; end
2
+
1
3
  #
2
- # Deprecated - handle deprecating and executing deprecated code
4
+ # Deprecated is a module to help you deprecate code BEFORE you remove it. Don't
5
+ # surprise your users, deprecate them!
3
6
  #
4
- # Version:: 2.0.1
5
- # Author:: Erik Hollensbe
6
- # License:: BSD
7
- # Copyright:: Copyright (c) 2006 Erik Hollensbe
8
- # Contact:: erik@hollensbe.org
7
+ # Usage is simple:
9
8
  #
10
- # Deprecated is intended to ease the programmer's control over
11
- # deprecating and handling deprecated code.
9
+ # class Foo
10
+ # include Deprecated
12
11
  #
13
- # Usage is simple:
12
+ # def moo
13
+ # "cow"
14
+ # end
15
+ #
16
+ # deprecated :moo
17
+ #
18
+ # def sheep
19
+ # "baaa"
20
+ # end
21
+ #
22
+ # deprecated :sheep, "Sounds#baa"
14
23
  #
15
- # # require 'rubygems' if need be
16
- # require 'deprecated'
17
- #
18
- # class Foo
19
- # private
20
- # # rename the original function and make it private
21
- # def monkey
22
- # do stuff...
24
+ # protected
25
+ #
26
+ # def bar
27
+ # true
28
+ # end
29
+ #
30
+ # deprecated :bar
23
31
  # end
24
- # # deprecate the function, this will create a 'monkey' method
25
- # # that will call the deprecate warnings
26
- # deprecate :monkey, :private
27
- # end
28
- #
29
- # The 'deprecated' call is injected into the 'Module' class at
30
- # require-time. This allows all classes that are newly-created to
31
- # access the 'deprecate' functionality. The deprecate definition must
32
- # follow the method definition. You may only define one deprecated
33
- # function per call.
34
- #
35
- # Methods deprecated default to 'public'. This is due to a limitation
36
- # in how Ruby handles permission definition. If you're aware of a
37
- # workaround to this problem, please let me know.
38
- #
39
- # You can however change this by providing an optional trailing
40
- # parameter to the 'deprecate' call:
41
- #
42
- # * :public - set the created method to be public
43
- # * :protected - set the created method to be protected
44
- # * :private - set the created method to be private
45
- #
46
- # Note: It's highly recommended that you make your original methods
47
- # private so that they cannot be accessed by outside code.
48
- #
49
- # Deprecated.set_action can change the default action (which is a
50
- # warning printed to stderr) if you prefer. This is ideal for code
51
- # sweeps where deprecated calls have to be removed. Please see the
52
- # documentation for this method to get an idea of the options that are
53
- # available.
54
- #
55
- #--
56
- #
57
- # The compilation of software known as deprecate.rb is distributed under the
58
- # following terms:
59
- # Copyright (C) 2005-2006 Erik Hollensbe. All rights reserved.
60
- #
61
- # Redistribution and use in source form, with or without
62
- # modification, are permitted provided that the following conditions
63
- # are met:
64
- #
65
- # 1. Redistributions of source code must retain the above copyright
66
- # notice, this list of conditions and the following disclaimer:
67
- #
68
- # THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
69
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
70
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
71
- # ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
72
- # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
73
- # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
74
- # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
75
- # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
76
- # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
77
- # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
78
- # SUCH DAMAGE.
79
- #
80
- #++
81
-
32
+ #
33
+ # Foo.new.moo # warns that the call is deprecated
34
+ #
35
+ # Deprecated.set_action(:raise)
36
+ # Foo.new.moo # raises with the same message
37
+ #
38
+ # Deprecated.set_action do |klass, sym, replacement|
39
+ # email_boss(
40
+ # "Someone tried to use #{klass}##{sym}! " +
41
+ # "They should be using #{replacement} instead!"
42
+ # )
43
+ # end
44
+ #
45
+ # Foo.new.sheep # do I really need to explain?
46
+ #
47
+ # Foo.new.bar # still protected!
48
+ #
49
+ # Let's do it live!
50
+ #
51
+ # class Bar
52
+ # include Deprecated
53
+ #
54
+ # # sets it just for this class
55
+ # deprecated_set_action do |klass, sym, replacement|
56
+ # email_boss(
57
+ # "Someone tried to use #{klass}##{sym}! " +
58
+ # "They should be using #{replacement} instead!"
59
+ # )
60
+ # end
61
+ #
62
+ # def cow
63
+ # "moo"
64
+ # end
65
+ #
66
+ # deprecate :cow # emails your boss when called!
67
+ # end
68
+ #
69
+ # Please see Deprecated::Module#deprecated, Deprecated.set_action, and
70
+ # Deprecated::Module#deprecated_set_action for more information.
71
+ #
82
72
  module Deprecated
83
-
84
- #
85
- # set_action defines the action that will be taken when code marked
86
- # deprecated is encountered. There are several stock options:
87
- #
88
- # * :warn -- print a warning message to stderr (default)
89
- # * :die -- warn and then terminate the program with error level -1
90
- # * :throw -- throw a DeprecatedError with the message
91
- #
92
- # If a proc is passed instead, it will execute that instead. This
93
- # procedure is passed a single argument, which is the name (NOT the
94
- # symbol) of the method in Class#meth syntax that was called. This
95
- # does not interrupt the calling process (unless you do so
96
- # yourself).
97
- #
98
- # The second argument is the message provided to warnings and throw
99
- # errors and so on. This message is a sprintf-like formatted string
100
- # that takes one argument, which is the Class#meth name as a string.
101
- # This message is not used when you define your own procedure.
102
- #
103
- # Note: ALL code that is marked deprecated will behave in the manner
104
- # that was set at the last call to set_action.
105
- #
106
- # Ex:
107
- #
108
- # # throws with the error message saying: "FIXME: Class#meth"
109
- # Deprecated.set_action(:throw, "FIXME: %s")
110
- #
111
- # # emails your boss everytime you run deprecated code
112
- # Deprecated.set_action proc do |msg|
113
- # f = IO.popen('mail boss@company -s "Joe still hasn't fixed %s"' % msg, 'w')
114
- # f.puts("Sorry, I still haven't fixed %s, please stop making me go to meetings.\n" % msg)
115
- # f.close
116
- # end
117
- #
118
-
119
- @@action = nil
120
-
121
- def Deprecated.action
122
- return @@action
123
- end
124
-
125
- def Deprecated.set_action(action, message="%s is deprecated.")
126
- if action.kind_of? Proc
127
- @@action = action
128
- return
73
+ VERSION = "3.0.0"
74
+
75
+ def __deprecated_run_action__(sym, replacement)
76
+ if self.class.instance_eval { @__deprecated_run_action__ }
77
+ self.class.instance_eval { @__deprecated_run_action__ }.call(self.class, sym, replacement)
78
+ else
79
+ Deprecated.run_action(self.class, sym, replacement)
80
+ end
129
81
  end
130
-
131
- case action
132
- when :warn
133
- @@action = proc do |msg|
134
- warn(message % msg)
135
- end
136
- when :die
137
- @@action = proc do |msg|
138
- warn(message % msg)
139
- exit(-1)
140
- end
141
- when :throw
142
- @@action = proc do |msg|
143
- raise DeprecatedError.new(message % msg)
144
- end
82
+
83
+ def self.build_message(klass, sym, replacement)
84
+ message = "#{klass}##{sym} is deprecated."
85
+
86
+ if replacement
87
+ message += " Please use #{replacement}."
88
+ end
89
+
90
+ return message
145
91
  end
146
- end
147
- end
148
92
 
149
- #
150
- # This is the class of the errors that the 'Deprecated' module will
151
- # throw if the action type is set to ':throw'.
152
- #
153
- # See Deprecated.set_action for more information.
154
- #
155
- class DeprecatedError < Exception
156
- attr_reader :message
157
- def initialize(msg=nil)
158
- @message = msg
159
- end
93
+ #
94
+ # set_action takes 3 "canned" arguments or an arbitrary block. If you
95
+ # provide the block, any canned argument is ignored.
96
+ #
97
+ # The canned arguments are:
98
+ #
99
+ # :warn:: display a warning
100
+ # :raise:: raise a DeprecatedError (a kind of StandardError) with the warning.
101
+ # :fail:: fail. die. kaput. it's over.
102
+ #
103
+ # Procs take three arguments:
104
+ #
105
+ # - The class of the method
106
+ # - The method name itself, a symbol
107
+ # - A replacement string which may be nil
108
+ #
109
+ def self.set_action(type=nil, &block)
110
+ @action = if block
111
+ block
112
+ else
113
+ case type
114
+ when :warn
115
+ proc { |*args| warn build_message(*args) }
116
+ when :fail
117
+ proc { |*args| fail build_message(*args) }
118
+ when :raise
119
+ proc { |*args| raise DeprecatedError, build_message(*args) }
120
+ else
121
+ raise ArgumentError, "you must provide a symbol or a block to set_action()."
122
+ end
123
+ end
124
+ end
125
+
126
+ #
127
+ # Is called when an action needs to be run. Proably not in your best
128
+ # interest to run this directly.
129
+ #
130
+ def self.run_action(klass, sym, replacement)
131
+ raise "run_action has no associated hook" unless @action
132
+ @action.call(klass, sym, replacement)
133
+ end
134
+
135
+ #
136
+ # Returns the current action; this may be block or Proc.
137
+ #
138
+ def self.action
139
+ @action
140
+ end
160
141
  end
161
142
 
162
- #
163
- # Start - inject the 'deprecated' method into the 'Module' class and
164
- # set the default action to warn.
165
- #
143
+ module Deprecated
144
+ module Module
145
+
146
+ #
147
+ # deprecated takes up to three arguments:
148
+ #
149
+ # - A symbol which is the name of the method you wish to deprecate
150
+ # (required)
151
+ # - A string or symbol which is the replacement method. If you provide
152
+ # this, your users will be instructed to use that method instead.
153
+ # - A symbol of :public, :private, or :protected which determines the
154
+ # new scope of the method. If you do not provide one, it will be
155
+ # searched for in the various collections, and scope will be chosen
156
+ # that way.
157
+ #
158
+ def deprecated(sym, replacement=nil, scope=nil)
159
+ unless sym.kind_of?(Symbol)
160
+ raise ArgumentError, "deprecated() requires symbols for its first argument."
161
+ end
166
162
 
167
- Module.send(:define_method, :deprecate,
168
- proc do |*args|
169
- sym = args.shift
170
- protection = args.shift || :public
171
-
172
- unless sym
173
- raise DeprecatedError.new("Invalid number of arguments passed to 'deprecated' function")
174
- end
175
-
176
- old_method = self.instance_method(sym)
177
-
178
- define_method(sym) do |*sendparams|
179
- Deprecated.action.call(self.class.to_s + '#' + sym.to_s)
180
- new_method = self.class.instance_method(sym)
181
- retval = old_method.bind(self).call(*sendparams)
182
- new_method.bind(self)
163
+ meth = instance_method(sym)
164
+ unless scope
165
+ pub = public_instance_methods
166
+ pro = protected_instance_methods
167
+ pri = private_instance_methods
168
+ if pub.include?(sym) or pub.include?(sym.to_s)
169
+ scope = :public
170
+ elsif pro.include?(sym) or pro.include?(sym.to_s)
171
+ scope = :protected
172
+ elsif pri.include?(sym) or pri.include?(sym.to_s)
173
+ scope = :private
174
+ end
175
+ end
176
+
177
+ define_method(sym) do |*args|
178
+ dep_meth = method(sym).unbind
179
+ __deprecated_run_action__(sym, replacement)
180
+ retval = meth.bind(self).call(*args)
181
+ dep_meth.bind(self)
183
182
  return retval
184
- end
185
-
186
- case protection
187
- when :public
188
- public(sym)
189
- when :private
190
- private(sym)
191
- when :protected
192
- protected(sym)
193
- end
194
-
195
- end)
183
+ end
196
184
 
197
- Deprecated.set_action(:warn)
185
+ method(scope).call(sym) if scope
186
+ return scope
187
+ end
198
188
 
199
- Deprecate = Deprecated
189
+ #
190
+ # Deprecated.set_action for class scope. See Deprecated.set_action.
191
+ #
192
+ def deprecated_set_action(&block)
193
+ raise "You must provide a block" unless block
194
+ @__deprecated_run_action__ = block
195
+ end
196
+ end
197
+
198
+ def self.included(base)
199
+ base.extend(Module)
200
+ end
201
+ end
202
+
203
+ Deprecated.set_action(:warn)
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ gem 'test-unit'
5
+ require 'test/unit'
6
+ require 'lib/deprecated.rb'
7
+
8
+ # this class is used to test the deprecate functionality
9
+ class DummyClass
10
+ include Deprecated
11
+
12
+ def monkey
13
+ return true
14
+ end
15
+
16
+ def monkey_bars
17
+ return true
18
+ end
19
+
20
+ deprecated :monkey
21
+ deprecated :monkey_bars, "FooClass#fart"
22
+
23
+ protected
24
+
25
+ def my_protected
26
+ return true
27
+ end
28
+
29
+ deprecated :my_protected
30
+
31
+ private
32
+
33
+ def my_private
34
+ return true
35
+ end
36
+
37
+ deprecated :my_private
38
+ end
39
+
40
+ class DummyClass2
41
+ include Deprecated
42
+
43
+ deprecated_set_action do |klass, sym, replacement|
44
+ raise DeprecatedError, "foo!"
45
+ end
46
+
47
+ def monkey
48
+ return true
49
+ end
50
+
51
+ deprecated :monkey
52
+ end
53
+
54
+ # we want exceptions for testing here.
55
+ Deprecated.set_action(:raise)
56
+
57
+ class DeprecateTest < Test::Unit::TestCase
58
+ def test_set_action
59
+ assert_raises(DeprecatedError) { DummyClass.new.monkey }
60
+
61
+ Deprecated.set_action { |klass, sym| raise DeprecatedError.new("#{klass}##{sym} is deprecated.") }
62
+ assert_raises(DeprecatedError.new("DummyClass#monkey is deprecated.")) do
63
+ DummyClass.new.monkey
64
+ end
65
+
66
+ Deprecated.set_action(:raise)
67
+
68
+ assert_raises(DeprecatedError.new("DummyClass#monkey is deprecated.")) do
69
+ DummyClass.new.monkey
70
+ end
71
+
72
+ # set to warn and make sure our return values are getting through.
73
+ Deprecated.set_action(:warn)
74
+ assert(DummyClass.new.monkey)
75
+
76
+ Kernel.module_eval {
77
+ def self.fail
78
+ raise "failed"
79
+ end
80
+ }
81
+
82
+ Deprecated.set_action(:fail)
83
+
84
+ assert_raises("failed") { DummyClass.new.monkey }
85
+ end
86
+
87
+ def test_scope
88
+ assert(
89
+ DummyClass.public_instance_methods.include?(:monkey) ||
90
+ DummyClass.public_instance_methods.include?("monkey")
91
+ )
92
+ assert(
93
+ DummyClass.protected_instance_methods.include?(:my_protected) ||
94
+ DummyClass.protected_instance_methods.include?("my_protected")
95
+ )
96
+ assert(
97
+ DummyClass.private_instance_methods.include?(:my_private) ||
98
+ DummyClass.private_instance_methods.include?("my_private")
99
+ )
100
+ end
101
+
102
+ def test_scoped_actions
103
+ assert_raises(DeprecatedError.new("foo!")) { DummyClass2.new.monkey }
104
+ end
105
+
106
+ def test_replacement
107
+ Deprecated.set_action(:raise)
108
+
109
+ assert_raises(DeprecatedError.new("DummyClass#monkey_bars is deprecated. Please use FooClass#fart.")) do
110
+ DummyClass.new.monkey_bars
111
+ end
112
+ end
113
+ end
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deprecated
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ prerelease: false
5
+ segments:
6
+ - 3
7
+ - 0
8
+ - 0
9
+ version: 3.0.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - Erik Hollensbe
@@ -9,7 +14,7 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2008-07-26 00:00:00 -07:00
17
+ date: 2010-05-05 00:00:00 -04:00
13
18
  default_executable:
14
19
  dependencies: []
15
20
 
@@ -22,10 +27,13 @@ extensions: []
22
27
  extra_rdoc_files: []
23
28
 
24
29
  files:
30
+ - Rakefile
25
31
  - lib/deprecated.rb
26
- - test/deprecated.rb
32
+ - test/test_deprecated.rb
27
33
  has_rdoc: true
28
34
  homepage:
35
+ licenses: []
36
+
29
37
  post_install_message:
30
38
  rdoc_options: []
31
39
 
@@ -35,20 +43,22 @@ required_ruby_version: !ruby/object:Gem::Requirement
35
43
  requirements:
36
44
  - - ">="
37
45
  - !ruby/object:Gem::Version
46
+ segments:
47
+ - 0
38
48
  version: "0"
39
- version:
40
49
  required_rubygems_version: !ruby/object:Gem::Requirement
41
50
  requirements:
42
51
  - - ">="
43
52
  - !ruby/object:Gem::Version
53
+ segments:
54
+ - 0
44
55
  version: "0"
45
- version:
46
56
  requirements: []
47
57
 
48
58
  rubyforge_project: deprecated
49
- rubygems_version: 1.1.1
59
+ rubygems_version: 1.3.6
50
60
  signing_key:
51
- specification_version: 2
61
+ specification_version: 3
52
62
  summary: An easy way to handle deprecating and conditionally running deprecated code
53
63
  test_files:
54
- - test/deprecated.rb
64
+ - test/test_deprecated.rb
@@ -1,33 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'lib/deprecated.rb'
4
- require 'test/unit'
5
-
6
- # this class is used to test the deprecate functionality
7
- class DummyClass
8
- def monkey
9
- return true
10
- end
11
-
12
- deprecate :monkey
13
- end
14
-
15
- # we want exceptions for testing here.
16
- Deprecate.set_action(:throw)
17
-
18
- class DeprecateTest < Test::Unit::TestCase
19
- def test_set_action
20
-
21
- assert_raise(DeprecatedError) { raise StandardError.new unless DummyClass.new.monkey }
22
-
23
- Deprecate.set_action(proc { |msg| raise DeprecatedError.new("#{msg} is deprecated.") })
24
-
25
- assert_raise(DeprecatedError) { raise StandardError.new unless DummyClass.new.monkey }
26
-
27
-
28
- # set to warn and make sure our return values are getting through.
29
- Deprecate.set_action(:warn)
30
-
31
- assert_nothing_raised(DeprecatedError) { raise StandardError.new unless DummyClass.new.monkey }
32
- end
33
- end