deprecated 1.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.
- data/lib/deprecated.rb +226 -0
- data/test/deprecated.rb +42 -0
- metadata +46 -0
data/lib/deprecated.rb
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Deprecate - handle deprecating and executing deprecated code
|
|
3
|
+
#
|
|
4
|
+
# Version:: 1.0.0
|
|
5
|
+
# Author:: Erik Hollensbe
|
|
6
|
+
# License:: BSD
|
|
7
|
+
# Copyright:: Copyright (c) 2006 Erik Hollensbe
|
|
8
|
+
# Contact:: erik@hollensbe.org
|
|
9
|
+
#
|
|
10
|
+
# Deprecate is intended to ease the programmer's control over
|
|
11
|
+
# deprecating and handling deprecated code.
|
|
12
|
+
#
|
|
13
|
+
# Usage is simple:
|
|
14
|
+
#
|
|
15
|
+
# # require 'rubygems' if need be
|
|
16
|
+
# require 'deprecate'
|
|
17
|
+
#
|
|
18
|
+
# class Foo
|
|
19
|
+
# private
|
|
20
|
+
# # rename the original function and make it private
|
|
21
|
+
# def _monkey
|
|
22
|
+
# do stuff...
|
|
23
|
+
# end
|
|
24
|
+
# public
|
|
25
|
+
# # deprecate the function, this will create a 'monkey' method
|
|
26
|
+
# # that will call the deprecate warnings
|
|
27
|
+
# deprecate :monkey, :_monkey
|
|
28
|
+
# end
|
|
29
|
+
#
|
|
30
|
+
# The 'deprecate' call is injected into the 'Module' class at
|
|
31
|
+
# require-time. This allows all classes that are newly-created to
|
|
32
|
+
# access the 'deprecate' functionality.
|
|
33
|
+
#
|
|
34
|
+
# The call itself takes a list of symbols. Each pair is first the name
|
|
35
|
+
# of the original function, the second the name of the current,
|
|
36
|
+
# renamed function. Both are represented as symbols.
|
|
37
|
+
#
|
|
38
|
+
# Ex:
|
|
39
|
+
#
|
|
40
|
+
# # foo subroutine is generated to call _foo, and notify the user
|
|
41
|
+
# # when called.
|
|
42
|
+
# deprecate :foo, :_foo
|
|
43
|
+
#
|
|
44
|
+
# You can define as many symbols as you like on one line as
|
|
45
|
+
# deprecated, but for obvious reasons the length of the list must be
|
|
46
|
+
# even. In the case that it isn't, the 'deprecate' call will throw an
|
|
47
|
+
# exception of type 'DeprecatedError'.
|
|
48
|
+
#
|
|
49
|
+
# If you prefer to have more sugar in your syntax, the call
|
|
50
|
+
# understands arrays:
|
|
51
|
+
#
|
|
52
|
+
# deprecate [:foo, :_foo], [:bar, :_bar]
|
|
53
|
+
#
|
|
54
|
+
# And of course, you can make the call multiple times.
|
|
55
|
+
#
|
|
56
|
+
# Methods deprecated default to 'public'. This is due to a limitation
|
|
57
|
+
# in how Ruby handles permission definition. If you're aware of a
|
|
58
|
+
# workaround to this problem, please let me know.
|
|
59
|
+
#
|
|
60
|
+
# You can however change this by providing an optional leading
|
|
61
|
+
# parameter to the 'deprecate' call:
|
|
62
|
+
#
|
|
63
|
+
# * :public - set the created method to be public
|
|
64
|
+
# * :protected - set the created method to be protected
|
|
65
|
+
# * :private - set the created method to be private
|
|
66
|
+
#
|
|
67
|
+
# Note: It's highly recommended that you make your original methods
|
|
68
|
+
# private so that they cannot be accessed by outside code.
|
|
69
|
+
#
|
|
70
|
+
# Deprecate.set_action can change the default action (which is a
|
|
71
|
+
# warning printed to stderr) if you prefer. This is ideal for code
|
|
72
|
+
# sweeps where deprecated calls have to be removed. Please see the
|
|
73
|
+
# documentation for this method to get an idea of the options that are
|
|
74
|
+
# available.
|
|
75
|
+
#
|
|
76
|
+
#--
|
|
77
|
+
#
|
|
78
|
+
# The compilation of software known as deprecate.rb is distributed under the
|
|
79
|
+
# following terms:
|
|
80
|
+
# Copyright (C) 2005-2006 Erik Hollensbe. All rights reserved.
|
|
81
|
+
#
|
|
82
|
+
# Redistribution and use in source form, with or without
|
|
83
|
+
# modification, are permitted provided that the following conditions
|
|
84
|
+
# are met:
|
|
85
|
+
#
|
|
86
|
+
# 1. Redistributions of source code must retain the above copyright
|
|
87
|
+
# notice, this list of conditions and the following disclaimer:
|
|
88
|
+
#
|
|
89
|
+
# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
90
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
91
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
92
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
93
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
94
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
95
|
+
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
96
|
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
97
|
+
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
98
|
+
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
99
|
+
# SUCH DAMAGE.
|
|
100
|
+
#
|
|
101
|
+
#++
|
|
102
|
+
|
|
103
|
+
module Deprecate
|
|
104
|
+
|
|
105
|
+
CALLER_REGEX = /\`([^\']+)/
|
|
106
|
+
|
|
107
|
+
#
|
|
108
|
+
# set_action defines the action that will be taken when code marked
|
|
109
|
+
# deprecated is encountered. There are several stock options:
|
|
110
|
+
#
|
|
111
|
+
# * :warn -- print a warning message to stderr (default)
|
|
112
|
+
# * :die -- warn and then terminate the program with error level -1
|
|
113
|
+
# * :throw -- throw a DeprecatedError with the message
|
|
114
|
+
#
|
|
115
|
+
# If a proc is passed instead, it will execute that instead. This
|
|
116
|
+
# procedure is passed a single argument, which is the name (NOT the
|
|
117
|
+
# symbol) of the method in Class#meth syntax that was called. This
|
|
118
|
+
# does not interrupt the calling process (unless you do so
|
|
119
|
+
# yourself).
|
|
120
|
+
#
|
|
121
|
+
# The second argument is the message provided to warnings and throw
|
|
122
|
+
# errors and so on. This message is a sprintf-like formatted string
|
|
123
|
+
# that takes one argument, which is the Class#meth name as a string.
|
|
124
|
+
# This message is not used when you define your own procedure.
|
|
125
|
+
#
|
|
126
|
+
# Note: ALL code that is marked deprecated will behave in the manner
|
|
127
|
+
# that was set at the last call to set_action.
|
|
128
|
+
#
|
|
129
|
+
# Ex:
|
|
130
|
+
#
|
|
131
|
+
# # throws with the error message saying: "FIXME: Class#meth"
|
|
132
|
+
# Deprecate.set_action(:throw, "FIXME: %s")
|
|
133
|
+
#
|
|
134
|
+
# # emails your boss everytime you run deprecated code
|
|
135
|
+
# Deprecate.set_action proc do |msg|
|
|
136
|
+
# f = IO.popen('mail boss@company -s "Joe still hasn't fixed %s"' % msg, 'w')
|
|
137
|
+
# f.puts("Sorry, I still haven't fixed %s, please stop making me go to meetings.\n" % msg)
|
|
138
|
+
# f.close
|
|
139
|
+
# end
|
|
140
|
+
#
|
|
141
|
+
|
|
142
|
+
@@action = nil
|
|
143
|
+
|
|
144
|
+
def Deprecate.action
|
|
145
|
+
return @@action
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def Deprecate.set_action(action, message="%s is deprecated.")
|
|
149
|
+
if action.kind_of? Proc
|
|
150
|
+
@@action = action
|
|
151
|
+
return
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
case action
|
|
155
|
+
when :warn
|
|
156
|
+
@@action = proc do |msg|
|
|
157
|
+
warn(message % msg)
|
|
158
|
+
end
|
|
159
|
+
when :die
|
|
160
|
+
@@action = proc do |msg|
|
|
161
|
+
warn(message % msg)
|
|
162
|
+
exit(-1)
|
|
163
|
+
end
|
|
164
|
+
when :throw
|
|
165
|
+
@@action = proc do |msg|
|
|
166
|
+
raise DeprecatedError.new(message % msg)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
#
|
|
173
|
+
# This is the class of the errors that the 'Deprecate' module will
|
|
174
|
+
# throw if the action type is set to ':throw'.
|
|
175
|
+
#
|
|
176
|
+
# See Deprecate.set_action for more information.
|
|
177
|
+
#
|
|
178
|
+
class DeprecatedError < Exception
|
|
179
|
+
attr_reader :message
|
|
180
|
+
def initialize(msg=nil)
|
|
181
|
+
@message = msg
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
#
|
|
186
|
+
# Start - inject the 'deprecated' method into the 'Module' class and
|
|
187
|
+
# set the default action to warn.
|
|
188
|
+
#
|
|
189
|
+
|
|
190
|
+
Module.send(:define_method, :deprecate,
|
|
191
|
+
proc do |*args|
|
|
192
|
+
args.flatten!
|
|
193
|
+
if args.length
|
|
194
|
+
|
|
195
|
+
permission = :public
|
|
196
|
+
|
|
197
|
+
if args.length % 2 != 0
|
|
198
|
+
permission = args.shift
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
while args.length > 0
|
|
202
|
+
syms = args.slice! 0, 2
|
|
203
|
+
|
|
204
|
+
if syms.include? nil
|
|
205
|
+
raise DeprecatedError.new("Invalid number of arguments passed to 'deprecated' function")
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
define_method(syms[0]) do |*sendparams|
|
|
209
|
+
Deprecate.action.call(self.class.to_s + '#' + syms[0].to_s)
|
|
210
|
+
self.send(syms[1], *sendparams)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
case permission
|
|
214
|
+
when :public
|
|
215
|
+
public(syms[0])
|
|
216
|
+
when :protected
|
|
217
|
+
protected(syms[0])
|
|
218
|
+
when :private
|
|
219
|
+
private(syms[0])
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
end)
|
|
225
|
+
|
|
226
|
+
Deprecate.set_action(:warn)
|
data/test/deprecated.rb
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'lib/deprecate.rb'
|
|
4
|
+
require 'test/unit'
|
|
5
|
+
|
|
6
|
+
# this class is used to test the deprecate functionality
|
|
7
|
+
class DummyClass
|
|
8
|
+
deprecate :monkey, :_monkey
|
|
9
|
+
|
|
10
|
+
def _monkey
|
|
11
|
+
return true
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# we want exceptions for testing here.
|
|
17
|
+
Deprecate.set_action(:throw)
|
|
18
|
+
|
|
19
|
+
class DeprecateTest < Test::Unit::TestCase
|
|
20
|
+
def set_action_builder
|
|
21
|
+
d = DummyClass.new
|
|
22
|
+
test = true
|
|
23
|
+
begin
|
|
24
|
+
d.monkey
|
|
25
|
+
test = false
|
|
26
|
+
rescue DeprecatedError => e
|
|
27
|
+
test = e.message == "DummyClass#monkey is deprecated."
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
return test
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# this inadvertently tests the deprecate functionality as well...
|
|
34
|
+
def test_set_action
|
|
35
|
+
|
|
36
|
+
assert(set_action_builder, "Deprecate.set_action message/:throw test")
|
|
37
|
+
|
|
38
|
+
Deprecate.set_action(proc { |msg| raise DeprecatedError.new("#{msg} is deprecated.") })
|
|
39
|
+
|
|
40
|
+
assert(set_action_builder, "Deprecate.set_action custom proc test")
|
|
41
|
+
end
|
|
42
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
rubygems_version: 0.8.11
|
|
3
|
+
specification_version: 1
|
|
4
|
+
name: deprecated
|
|
5
|
+
version: !ruby/object:Gem::Version
|
|
6
|
+
version: 1.0.0
|
|
7
|
+
date: 2006-02-15 00:00:00 -08:00
|
|
8
|
+
summary: An easy way to handle deprecating and conditionally running deprecated code
|
|
9
|
+
require_paths:
|
|
10
|
+
- lib
|
|
11
|
+
email: erik@hollensbe.org
|
|
12
|
+
homepage:
|
|
13
|
+
rubyforge_project: deprecated
|
|
14
|
+
description:
|
|
15
|
+
autorequire: deprecated
|
|
16
|
+
default_executable:
|
|
17
|
+
bindir: bin
|
|
18
|
+
has_rdoc: true
|
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
20
|
+
requirements:
|
|
21
|
+
- - ">"
|
|
22
|
+
- !ruby/object:Gem::Version
|
|
23
|
+
version: 0.0.0
|
|
24
|
+
version:
|
|
25
|
+
platform: ruby
|
|
26
|
+
signing_key:
|
|
27
|
+
cert_chain:
|
|
28
|
+
authors:
|
|
29
|
+
- Erik Hollensbe
|
|
30
|
+
files:
|
|
31
|
+
- lib/deprecated.rb
|
|
32
|
+
- test/deprecated.rb
|
|
33
|
+
test_files:
|
|
34
|
+
- test/deprecated.rb
|
|
35
|
+
rdoc_options: []
|
|
36
|
+
|
|
37
|
+
extra_rdoc_files: []
|
|
38
|
+
|
|
39
|
+
executables: []
|
|
40
|
+
|
|
41
|
+
extensions: []
|
|
42
|
+
|
|
43
|
+
requirements: []
|
|
44
|
+
|
|
45
|
+
dependencies: []
|
|
46
|
+
|