deprecated 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/deprecated.rb +226 -0
  2. data/test/deprecated.rb +42 -0
  3. metadata +46 -0
@@ -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)
@@ -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
+