deprecate_public 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 025fabce1f816909e8411a204224ee6e7f725678
4
- data.tar.gz: e6ad2a3fbcb5836b2fc701160bf064794e81ed37
2
+ SHA256:
3
+ metadata.gz: ab37faf4d1b174216b1792ae0445c764e6496021a352d8a10f679585a275609a
4
+ data.tar.gz: bce063415049ac301059cda3f01aa78496326faaab26a481f4db49c805bdcf47
5
5
  SHA512:
6
- metadata.gz: 1adfd5e7564c6d009116bff272d51ae20522db1ac2310d305f864e2826e3318802f012303433cfb703042cc3e0f59a0afba2cdc5d8f8173737eff6692f3af2fa
7
- data.tar.gz: bc32579cfe6621f694c9c8dec37b37caf758eadb6e24e619eff279a18ffc195b4ac9f9d6b4fe1981282775650d06f86554327f266d087f90f195f41e92ae7bb6
6
+ metadata.gz: ebb882d17816dd086e6470db2d0ca46ad3672e16706f827ee39070367bcbbe4120f8e2aff8f383eac29ac5a94d8c026738f83a9ecb6cd65fc5aecbef5a58f1fd
7
+ data.tar.gz: 364e7d2e9eb435e6d1896a4ea5f603fe1828f7a30b0d2b8bf2aa7bd2a3bd42b2ff3927c6e2ab51f4eed7ad07556fed4cdcafca314e1c37abc908a98459171db0
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ === 1.1.0 (2019-04-24)
2
+
3
+ * Add Module#deprecate_public_constant on Ruby 2.6+ (jeremyevans)
4
+
5
+ * Work on Ruby 1.8+, fix tests on Ruby 2.0-2.4 (jeremyevans)
6
+
1
7
  === 1.0.0 (2017-12-13)
2
8
 
3
9
  * Initial public release
@@ -5,6 +5,10 @@ existing public method in one of their classes, and make it a
5
5
  private method, but still allow it to be called as a public method,
6
6
  emitting a warning if called as a public method.
7
7
 
8
+ On Ruby 2.6+, you can also take an existing public constant,
9
+ make it a private constant, but still allow it to be accessed as a
10
+ public constant, emitting a warning if accessed as a public constant.
11
+
8
12
  == Usage
9
13
 
10
14
  === Basic
@@ -31,6 +35,21 @@ emitting a warning if called as a public method.
31
35
  # warning emitting: "calling Foo#meth using deprecated public interface"
32
36
  # => :return_value
33
37
 
38
+ ## Ruby 2.6+: Deprecating Constants
39
+
40
+ class Foo
41
+ BAR = 1
42
+ private_constant :BAR
43
+ end
44
+
45
+ Foo::BAR
46
+ # raises NameError: private constant Foo::BAR referenced
47
+
48
+ Foo.deprecate_public_constant :Bar
49
+ Foo::BAR
50
+ # warning emitting: "accessing Foo::BAR using deprecated public interface"
51
+ # => 1
52
+
34
53
  === Arguments
35
54
 
36
55
  # Deprecate multiple methods at once
@@ -39,19 +58,26 @@ emitting a warning if called as a public method.
39
58
  # Override message
40
59
  deprecate_public(:meth1, "meth1 is private method, stop calling it!")
41
60
 
61
+ # Ruby 2.6+: deprecate_public_constant uses same interface
62
+
42
63
  == Design
43
64
 
44
- deprecate_public works by overriding method_missing, which is called
65
+ +deprecate_public+ works by overriding +method_missing+, which is called
45
66
  if you call a private method with a specified receiver. That's one
46
- of the reasons calling a private method raises NoMethodError instead
47
- of MethodVisibilityError or something like that.
67
+ of the reasons calling a private method raises +NoMethodError+ instead
68
+ of +MethodVisibilityError+ or something like that.
69
+
70
+ On Ruby 2.6+, +deprecate_public_constant+ works by overriding
71
+ +const_missing+, which is called if you access a constant using the
72
+ public interface (<tt>Foo::BAR</tt> in the above example).
48
73
 
49
74
  == Caveats
50
75
 
51
76
  While you can call +deprecate_public+ on a Module, you should only do so
52
77
  if the module has not been included in another Module or Class, as when
53
78
  called on a module it only affects future cases where the module was
54
- included in a class.
79
+ included in a class. The same is true for +deprecate_public_constant+
80
+ on Ruby 2.6+..
55
81
 
56
82
  == Installation
57
83
 
@@ -2,14 +2,16 @@ class Module
2
2
  module DeprecatePublic
3
3
  # Handle calls to methods where +deprecate_public+ has been called
4
4
  # for the method, printing the warning and then using +send+ to
5
- #invoke the method.
5
+ # invoke the method.
6
6
  def method_missing(meth, *args, &block)
7
7
  check_meth = "_deprecated_public_message_#{meth}"
8
8
  if respond_to?(meth, true) && respond_to?(check_meth, true) && (msg = send(check_meth))
9
9
  if RUBY_VERSION >= '2.5'
10
10
  Kernel.warn(msg, :uplevel => 1)
11
+ elsif RUBY_VERSION >= '2.0'
12
+ Kernel.warn("#{caller(1,1)[0].sub(/in `.*'\z/, '')} warning: #{msg}")
11
13
  else
12
- Kernel.warn(msg)
14
+ Kernel.warn("#{caller(1)[0].sub(/in `.*'\z/, '')} warning: #{msg}")
13
15
  end
14
16
 
15
17
  send(meth, *args, &block)
@@ -35,4 +37,38 @@ class Module
35
37
 
36
38
  nil
37
39
  end
40
+
41
+ if RUBY_VERSION >= '2.6'
42
+ module DeprecatePublicConstant
43
+ # Handle access to constants where +deprecate_public_constant+ has been called
44
+ # for the constant, printing the warning and then using +const_get+ to
45
+ # access the constant.
46
+ def const_missing(const)
47
+ check_meth = "_deprecated_public_constant_message_#{const}"
48
+ if const_defined?(const, true) && respond_to?(check_meth, true) && (msg = send(check_meth))
49
+ Kernel.warn(msg, :uplevel => 1)
50
+ const_get(const, true)
51
+ else
52
+ super
53
+ end
54
+ end
55
+ end
56
+
57
+ # Allow but deprecate public constant access to +const+, if +const+ is
58
+ # a private constant. +const+ can be an array of method name strings
59
+ # or symbols to handle multiple methods at once. If +msg+ is specified,
60
+ # it can be used to customize the warning printed.
61
+ def deprecate_public_constant(const, msg=nil)
62
+ extend DeprecatePublicConstant
63
+
64
+ Array(const).each do |c|
65
+ message = (msg || "accessing #{name}::#{c} using deprecated public interface").dup.freeze
66
+ message_meth = :"_deprecated_public_constant_message_#{c}"
67
+ define_singleton_method(message_meth){message}
68
+ singleton_class.send(:private, message_meth)
69
+ end
70
+
71
+ nil
72
+ end
73
+ end
38
74
  end
@@ -1,16 +1,39 @@
1
1
  require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'lib', 'deprecate_public')
2
2
  require 'rubygems'
3
+ ENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins
3
4
  gem 'minitest'
4
5
  require 'minitest/autorun'
5
6
 
6
7
  warnings = []
7
8
  (class << Kernel; self; end).module_eval do
8
9
  define_method(:warn) do |*args|
9
- warnings << args.first
10
+ warnings << if args.last == {:uplevel => 1}
11
+ args.first
12
+ else
13
+ args.first.sub(/\A.+warning: (.+)\z/, '\1')
14
+ end
10
15
  end
11
16
  end
12
17
 
13
18
  class DPSTest
19
+ if RUBY_VERSION >= '2.6'
20
+ PUB = 1
21
+
22
+ DEPPUB = 2
23
+ deprecate_public_constant :DEPPUB
24
+
25
+ PRIV = 3
26
+ private_constant :PRIV
27
+
28
+ DEPPRIV = 4
29
+ private_constant :DEPPRIV
30
+ deprecate_public_constant :DEPPRIV
31
+
32
+ DEPPRIV2 = 5
33
+ private_constant :DEPPRIV2
34
+ deprecate_public_constant :DEPPRIV2, "custom warning for DEPPRIV2"
35
+ end
36
+
14
37
  def pub; 1 end
15
38
  def dep_pub; 8 end
16
39
  deprecate_public(:dep_pub)
@@ -51,6 +74,7 @@ end
51
74
  describe "Module#deprecate_public" do
52
75
  before do
53
76
  @obj = DPSTest.new
77
+ warnings.clear
54
78
  end
55
79
 
56
80
  after do
@@ -106,3 +130,45 @@ describe "Module#deprecate_public" do
106
130
  proc{@obj.dep_priv}.must_raise NoMethodError
107
131
  end
108
132
  end
133
+
134
+ if RUBY_VERSION >= '2.6'
135
+ describe "Module#deprecate_public_constant" do
136
+ before do
137
+ warnings.clear
138
+ end
139
+ after do
140
+ warnings.must_equal []
141
+ end
142
+
143
+ it "should not warn for constant if deprecate_public_constant is not used and access should be allowed" do
144
+ DPSTest::PUB.must_equal 1
145
+ class DPSTest
146
+ PRIV.must_equal 3
147
+ end
148
+ end
149
+
150
+ it "should raise NameError for private constants if deprecate_public_constant is not used" do
151
+ proc{DPSTest::PRIV}.must_raise NameError
152
+ end
153
+
154
+ it "should not warn if constants are public and deprecate_public_constant is used" do
155
+ DPSTest::DEPPUB.must_equal 2
156
+ end
157
+
158
+ it "should warn if constants are private and deprecate_public_constant is used" do
159
+ DPSTest::DEPPRIV.must_equal 4
160
+ DPSTest::DEPPRIV2.must_equal 5
161
+ warnings.must_equal [
162
+ "accessing DPSTest::DEPPRIV using deprecated public interface",
163
+ "custom warning for DEPPRIV2"
164
+ ]
165
+ warnings.clear
166
+ end
167
+
168
+ it "should raise NameError if the constant is not defined" do
169
+ c = Class.new
170
+ c.deprecate_public_constant :PUB
171
+ proc{c::PUB}.must_raise NameError
172
+ end
173
+ end
174
+ end
metadata CHANGED
@@ -1,16 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deprecate_public
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-13 00:00:00.000000000 Z
11
+ date: 2019-04-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Warn when calling private methods via public interface
13
+ description: Warn when calling private methods and accessing private constants via
14
+ public interface
14
15
  email: code@jeremyevans.net
15
16
  executables: []
16
17
  extensions: []
@@ -35,7 +36,8 @@ rdoc_options:
35
36
  - "--inline-source"
36
37
  - "--line-numbers"
37
38
  - "--title"
38
- - 'deprecate_public: Warn when calling private methods via public interface'
39
+ - 'deprecate_public: Warn when calling private methods and accessing private constants
40
+ via public interface'
39
41
  - "--main"
40
42
  - README.rdoc
41
43
  require_paths:
@@ -51,9 +53,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
51
53
  - !ruby/object:Gem::Version
52
54
  version: '0'
53
55
  requirements: []
54
- rubyforge_project:
55
- rubygems_version: 2.6.13
56
+ rubygems_version: 3.0.3
56
57
  signing_key:
57
58
  specification_version: 4
58
- summary: Warn when calling private methods via public interface
59
+ summary: Warn when calling private methods and accessing private constants via public
60
+ interface
59
61
  test_files: []