deprecated 2.0.1 → 3.0.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.
@@ -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