Author: kclark
Date: Tue Jun 17 18:01:07 2008
New Revision: 668926
URL: http://svn.apache.org/viewvc?rev=668926&view=rev
Log:
deprecate_class! now sets up a proxy class that logs a warning when used
Modified:
incubator/thrift/trunk/lib/rb/lib/thrift/deprecation.rb
incubator/thrift/trunk/lib/rb/spec/deprecation_spec.rb
Modified: incubator/thrift/trunk/lib/rb/lib/thrift/deprecation.rb
URL:
http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/rb/lib/thrift/deprecation.rb?rev=668926&r1=668925&r2=668926&view=diff
==============================================================================
--- incubator/thrift/trunk/lib/rb/lib/thrift/deprecation.rb (original)
+++ incubator/thrift/trunk/lib/rb/lib/thrift/deprecation.rb Tue Jun 17 18:01:07
2008
@@ -31,6 +31,42 @@
end
end
+module Thrift::DeprecationProxy
+ def self.new(obj)
+ Class.new(obj) do
+ klass = self
+ @@self = klass
+ @@obj = obj
+ instance_methods.sort.reject { |x| [:__id__,:__send__].include? x.to_sym
}.each do |sym|
+ undef_method sym
+ end
+ def method_missing(sym, *args, &block)
+ @@obj.instance_method(sym).bind(self).call(*args, &block)
+ end
+ (class << self;self;end).class_eval do
+ @@self = klass
+ @@obj = obj
+ @@warned = false
+ instance_methods.sort.reject { |x| [:__id__,:__send__].include?
x.to_sym }.each do |sym|
+ undef_method sym
+ end
+ def method_missing(sym, *args, &block)
+ unless @@warned
+ STDERR.puts "Warning: class #{@@obj.inspect} is deprecated"
+ STDERR.puts " from #{caller.first}"
+ @@warned = true
+ end
+ if @@self.__id__ == self.__id__
+ @@obj.send sym, *args, &block
+ else
+ @@obj.method(sym).unbind.bind(self).call(*args, &block)
+ end
+ end
+ end
+ end
+ end
+end
+
module Kernel
# Provides an alternate name for the class for deprecation purposes
# Example:
@@ -39,13 +75,10 @@
# at the moment this only works for creating top-level constants
# if necessary, this can be extended to take something like
:'Thrift::TBinaryProtocol'
# alternately, Module can be extended with a similar method
- #
- # another idea is to not make the old name a pointer to the new, but rather
- # a pointer to a proxy class that logs deprecation warnings and forwards
methods
def deprecate_class!(klasses)
return unless Thrift::DEPRECATION
klasses.each_pair do |old, new|
- Object.const_set old, new
+ Object.const_set old, Thrift::DeprecationProxy.new(new)
end
end
end
Modified: incubator/thrift/trunk/lib/rb/spec/deprecation_spec.rb
URL:
http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/rb/spec/deprecation_spec.rb?rev=668926&r1=668925&r2=668926&view=diff
==============================================================================
--- incubator/thrift/trunk/lib/rb/spec/deprecation_spec.rb (original)
+++ incubator/thrift/trunk/lib/rb/spec/deprecation_spec.rb Tue Jun 17 18:01:07
2008
@@ -168,6 +168,12 @@
describe "deprecate_class!" do
it_should_behave_like "deprecation"
+ def stub_stderr(callstr, offset=1)
+ STDERR.should_receive(:puts).with("Warning: class #{callstr} is
deprecated")
+ line = caller.first[/\d+$/].to_i + offset
+ STDERR.should_receive(:puts).with(" from #{__FILE__}:#{line}")
+ end
+
it "should create a new global constant that points to the old one" do
begin
klass = Class.new do
@@ -176,6 +182,7 @@
end
end
deprecate_class! :DeprecationSpecOldClass => klass
+ stub_stderr(klass)
::DeprecationSpecOldClass.should eql(klass)
::DeprecationSpecOldClass.new.foo.should == "foo"
ensure
@@ -194,10 +201,32 @@
end
deprecate_class! :DeprecationSpecOldClass => klass
end
+ stub_stderr(klass)
::DeprecationSpecOldClass.should eql(klass)
::DeprecationSpecOldClass.new.foo.should == "foo"
ensure
Object.send :remove_const, :DeprecationSpecOldClass if
Object.const_defined? :DeprecationSpecOldClass
end
end
+
+ it "should not prevent the deprecated class from being a superclass" do
+ begin
+ klass = Class.new do
+ def foo
+ "foo"
+ end
+ end
+ deprecate_class! :DeprecationSpecOldClass => klass
+ subklass = Class.new(::DeprecationSpecOldClass) do
+ def foo
+ "subclass #{super}"
+ end
+ end
+ stub_stderr(klass)
+ subklass.superclass.should eql(klass)
+ subklass.new.foo.should == "subclass foo"
+ ensure
+ Object.send :remove_const, :DeprecationSpecOldClass if
Object.const_defined? :DeprecationSpecOldClass
+ end
+ end
end