deprecate_public 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +3 -0
- data/MIT-LICENSE +18 -0
- data/README.rdoc +76 -0
- data/Rakefile +23 -0
- data/lib/deprecate_public.rb +38 -0
- data/test/deprecate_public_test.rb +108 -0
- metadata +59 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 025fabce1f816909e8411a204224ee6e7f725678
|
4
|
+
data.tar.gz: e6ad2a3fbcb5836b2fc701160bf064794e81ed37
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1adfd5e7564c6d009116bff272d51ae20522db1ac2310d305f864e2826e3318802f012303433cfb703042cc3e0f59a0afba2cdc5d8f8173737eff6692f3af2fa
|
7
|
+
data.tar.gz: bc32579cfe6621f694c9c8dec37b37caf758eadb6e24e619eff279a18ffc195b4ac9f9d6b4fe1981282775650d06f86554327f266d087f90f195f41e92ae7bb6
|
data/CHANGELOG
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright (c) 2017 Jeremy Evans
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to
|
5
|
+
deal in the Software without restriction, including without limitation the
|
6
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
7
|
+
sell copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
16
|
+
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
= ruby-deprecate_public
|
2
|
+
|
3
|
+
ruby-deprecate_public exists so that library authors can take an
|
4
|
+
existing public method in one of their classes, and make it a
|
5
|
+
private method, but still allow it to be called as a public method,
|
6
|
+
emitting a warning if called as a public method.
|
7
|
+
|
8
|
+
== Usage
|
9
|
+
|
10
|
+
=== Basic
|
11
|
+
|
12
|
+
require 'deprecate_public'
|
13
|
+
class Foo
|
14
|
+
private
|
15
|
+
|
16
|
+
def meth
|
17
|
+
:return_value
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
foo = Foo.new
|
22
|
+
|
23
|
+
foo.send(:meth)
|
24
|
+
# => :return_value
|
25
|
+
|
26
|
+
foo.meth
|
27
|
+
# raises NoMethodError: private method `meth' called for ...
|
28
|
+
|
29
|
+
Foo.deprecate_public :meth
|
30
|
+
foo.meth
|
31
|
+
# warning emitting: "calling Foo#meth using deprecated public interface"
|
32
|
+
# => :return_value
|
33
|
+
|
34
|
+
=== Arguments
|
35
|
+
|
36
|
+
# Deprecate multiple methods at once
|
37
|
+
deprecate_public([:meth1, :meth2])
|
38
|
+
|
39
|
+
# Override message
|
40
|
+
deprecate_public(:meth1, "meth1 is private method, stop calling it!")
|
41
|
+
|
42
|
+
== Design
|
43
|
+
|
44
|
+
deprecate_public works by overriding method_missing, which is called
|
45
|
+
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.
|
48
|
+
|
49
|
+
== Caveats
|
50
|
+
|
51
|
+
While you can call +deprecate_public+ on a Module, you should only do so
|
52
|
+
if the module has not been included in another Module or Class, as when
|
53
|
+
called on a module it only affects future cases where the module was
|
54
|
+
included in a class.
|
55
|
+
|
56
|
+
== Installation
|
57
|
+
|
58
|
+
ruby-deprecate_public is distributed as a gem, and can be installed with:
|
59
|
+
|
60
|
+
gem install deprecate_public
|
61
|
+
|
62
|
+
== Source
|
63
|
+
|
64
|
+
ruby-deprecate_public is hosted on GitHub:
|
65
|
+
|
66
|
+
https://github.com/jeremyevans/ruby-deprecate_public
|
67
|
+
|
68
|
+
== Issues
|
69
|
+
|
70
|
+
ruby-deprecate_public uses GitHub Issues for issue tracking:
|
71
|
+
|
72
|
+
https://github.com/jeremyevans/ruby-deprecate_public/issues
|
73
|
+
|
74
|
+
== Author
|
75
|
+
|
76
|
+
Jeremy Evans <code@jeremyevans.net>
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "rake"
|
2
|
+
require "rake/clean"
|
3
|
+
require "rdoc/task"
|
4
|
+
|
5
|
+
CLEAN.include ["*.gem", "rdoc"]
|
6
|
+
RDOC_OPTS = ['--inline-source', '--line-numbers', '--title', 'deprecate_public: Warn when calling private methods via public interface', '--main', 'README.rdoc', '-f', 'hanna']
|
7
|
+
|
8
|
+
RDoc::Task.new do |rdoc|
|
9
|
+
rdoc.rdoc_dir = "rdoc"
|
10
|
+
rdoc.options += RDOC_OPTS
|
11
|
+
rdoc.rdoc_files.add %w"lib/deprecate_public.rb MIT-LICENSE CHANGELOG README.rdoc"
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Run specs"
|
15
|
+
task :test do
|
16
|
+
sh "#{FileUtils::RUBY} -v test/deprecate_public_test.rb"
|
17
|
+
end
|
18
|
+
task :default=>[:test]
|
19
|
+
|
20
|
+
desc "Package deprecate_public"
|
21
|
+
task :package=>[:clean] do
|
22
|
+
sh "#{FileUtils::RUBY} -S gem build deprecate_public.gemspec"
|
23
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class Module
|
2
|
+
module DeprecatePublic
|
3
|
+
# Handle calls to methods where +deprecate_public+ has been called
|
4
|
+
# for the method, printing the warning and then using +send+ to
|
5
|
+
#invoke the method.
|
6
|
+
def method_missing(meth, *args, &block)
|
7
|
+
check_meth = "_deprecated_public_message_#{meth}"
|
8
|
+
if respond_to?(meth, true) && respond_to?(check_meth, true) && (msg = send(check_meth))
|
9
|
+
if RUBY_VERSION >= '2.5'
|
10
|
+
Kernel.warn(msg, :uplevel => 1)
|
11
|
+
else
|
12
|
+
Kernel.warn(msg)
|
13
|
+
end
|
14
|
+
|
15
|
+
send(meth, *args, &block)
|
16
|
+
else
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Allow but deprecate public method calls to +meth+, if +meth+ is
|
23
|
+
# protected or private. +meth+ can be an array of method name strings
|
24
|
+
# or symbols to handle multiple methods at once. If +msg+ is specified,
|
25
|
+
# it can be used to customize the warning printed.
|
26
|
+
def deprecate_public(meth, msg=nil)
|
27
|
+
include DeprecatePublic
|
28
|
+
|
29
|
+
Array(meth).each do |m|
|
30
|
+
message = (msg || "calling #{name}##{m} using deprecated public interface").dup.freeze
|
31
|
+
message_meth = :"_deprecated_public_message_#{m}"
|
32
|
+
define_method(message_meth){message}
|
33
|
+
private message_meth
|
34
|
+
end
|
35
|
+
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'lib', 'deprecate_public')
|
2
|
+
require 'rubygems'
|
3
|
+
gem 'minitest'
|
4
|
+
require 'minitest/autorun'
|
5
|
+
|
6
|
+
warnings = []
|
7
|
+
(class << Kernel; self; end).module_eval do
|
8
|
+
define_method(:warn) do |*args|
|
9
|
+
warnings << args.first
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class DPSTest
|
14
|
+
def pub; 1 end
|
15
|
+
def dep_pub; 8 end
|
16
|
+
deprecate_public(:dep_pub)
|
17
|
+
|
18
|
+
def test_prot(other)
|
19
|
+
other.prot
|
20
|
+
end
|
21
|
+
def test_dep_prot(other)
|
22
|
+
other.dep_prot
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def prot; 2 end
|
28
|
+
def dep_prot; 9 end
|
29
|
+
deprecate_public(:dep_prot)
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def priv; 3 end
|
34
|
+
def dep_priv; 4 end
|
35
|
+
deprecate_public(:dep_priv)
|
36
|
+
|
37
|
+
def dep_priv1; 5 end
|
38
|
+
def dep_priv2; 6 end
|
39
|
+
deprecate_public([:dep_priv1, :dep_priv2])
|
40
|
+
|
41
|
+
def dep_priv_msg; 7 end
|
42
|
+
deprecate_public(:dep_priv_msg, "custom warning for dep_priv_msg")
|
43
|
+
end
|
44
|
+
|
45
|
+
class DPSTest2
|
46
|
+
def test_dep_prot(other)
|
47
|
+
other.dep_prot
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "Module#deprecate_public" do
|
52
|
+
before do
|
53
|
+
@obj = DPSTest.new
|
54
|
+
end
|
55
|
+
|
56
|
+
after do
|
57
|
+
warnings.must_equal []
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should not warn for methods if deprecate_public is not used and access should be allowed" do
|
61
|
+
@obj.pub.must_equal 1
|
62
|
+
@obj.test_prot(DPSTest.new).must_equal 2
|
63
|
+
@obj.instance_exec do
|
64
|
+
prot.must_equal 2
|
65
|
+
priv.must_equal 3
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should raise NoMethodError for private/protected method calls if deprecate_public is not used" do
|
70
|
+
proc{@obj.prot}.must_raise NoMethodError
|
71
|
+
proc{@obj.priv}.must_raise NoMethodError
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should not warn if methods are public and deprecate_public is used" do
|
75
|
+
@obj.dep_pub.must_equal 8
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should not warn if methods are protected and deprecate_public is used and access should be allowed" do
|
79
|
+
@obj.test_dep_prot(DPSTest.new).must_equal 9
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should warn if methods are private and deprecate_public is used" do
|
83
|
+
@obj.dep_priv.must_equal 4
|
84
|
+
@obj.dep_priv1.must_equal 5
|
85
|
+
@obj.dep_priv2.must_equal 6
|
86
|
+
@obj.dep_priv_msg.must_equal 7
|
87
|
+
warnings.must_equal [
|
88
|
+
"calling DPSTest#dep_priv using deprecated public interface",
|
89
|
+
"calling DPSTest#dep_priv1 using deprecated public interface",
|
90
|
+
"calling DPSTest#dep_priv2 using deprecated public interface",
|
91
|
+
"custom warning for dep_priv_msg"
|
92
|
+
]
|
93
|
+
warnings.clear
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should warn if methods are protected and deprecate_public is used" do
|
97
|
+
DPSTest2.new.test_dep_prot(@obj).must_equal 9
|
98
|
+
warnings.must_equal ["calling DPSTest#dep_prot using deprecated public interface"]
|
99
|
+
warnings.clear
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should raise NoMethodError if the method is not defined" do
|
103
|
+
class << @obj
|
104
|
+
undef :dep_priv
|
105
|
+
end
|
106
|
+
proc{@obj.dep_priv}.must_raise NoMethodError
|
107
|
+
end
|
108
|
+
end
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: deprecate_public
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeremy Evans
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-12-13 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Warn when calling private methods via public interface
|
14
|
+
email: code@jeremyevans.net
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files:
|
18
|
+
- README.rdoc
|
19
|
+
- CHANGELOG
|
20
|
+
- MIT-LICENSE
|
21
|
+
files:
|
22
|
+
- CHANGELOG
|
23
|
+
- MIT-LICENSE
|
24
|
+
- README.rdoc
|
25
|
+
- Rakefile
|
26
|
+
- lib/deprecate_public.rb
|
27
|
+
- test/deprecate_public_test.rb
|
28
|
+
homepage: https://github.com/jeremyevans/ruby-deprecate_public
|
29
|
+
licenses:
|
30
|
+
- MIT
|
31
|
+
metadata: {}
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options:
|
34
|
+
- "--quiet"
|
35
|
+
- "--inline-source"
|
36
|
+
- "--line-numbers"
|
37
|
+
- "--title"
|
38
|
+
- 'deprecate_public: Warn when calling private methods via public interface'
|
39
|
+
- "--main"
|
40
|
+
- README.rdoc
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
requirements: []
|
54
|
+
rubyforge_project:
|
55
|
+
rubygems_version: 2.6.13
|
56
|
+
signing_key:
|
57
|
+
specification_version: 4
|
58
|
+
summary: Warn when calling private methods via public interface
|
59
|
+
test_files: []
|