fig_leaf 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/fig_leaf.rb +82 -0
  2. metadata +48 -0
@@ -0,0 +1,82 @@
1
+ # Tools for making inherited interfaces private to a class.
2
+ module FigLeaf
3
+ module Macros
4
+ private
5
+ # Given a list of classes, modules, strings, and symbols, compile
6
+ # a combined list of methods. Classes and modules will be queried
7
+ # for their instance methods; strings and symbols will be treated
8
+ # as method names.
9
+ #
10
+ # Once the list is compiled, make all of the methods private.
11
+ #
12
+ # Takes an optional options hash, which can include the following options:
13
+ #
14
+ # - :ancestors is a boolean determining whether to consider
15
+ # ancestors classes and modules.
16
+ #
17
+ # - :except is a list of classes, modules, and method names which
18
+ # will be excluded from treatment.
19
+ def hide(*stuff)
20
+ hide_methods(self, [Object], *stuff)
21
+ end
22
+
23
+ # Like #hide, only hides methods at the class/module level.
24
+ def hide_singletons(*stuff)
25
+ hide_methods(singleton_class, [Class], *stuff)
26
+ end
27
+
28
+ # The shared bits of #hide and #hide_singletons
29
+ def hide_methods(mod, except_defaults, *stuff)
30
+ options = stuff.last.is_a?(Hash) ? stuff.pop : {}
31
+ include_ancestors = options.fetch(:ancestors){false}
32
+ except = Array(options.fetch(:except){except_defaults})
33
+ protect = Array(options[:protect])
34
+ except_methods = collect_methods(true, *except)
35
+ protect_methods = collect_methods(true, *protect)
36
+ methods_to_hide = collect_methods(include_ancestors, *stuff)
37
+ (methods_to_hide - except_methods).each do |method_name|
38
+ mod.module_eval do
39
+ next unless method_defined?(method_name)
40
+ if protect_methods.include?(method_name)
41
+ protected method_name
42
+ else
43
+ private method_name
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ # Given a list of classes, modules, strings, and symbols, compile
50
+ # a combined list of methods. Classes and modules will be queried
51
+ # for their instance methods; strings and symbols will be treated
52
+ # as methods names. +include_ancestors+ determines whether to
53
+ # include methods defined by class/module ancestors.
54
+ def collect_methods(include_ancestors, *methods_or_modules)
55
+ methods_or_modules.inject([]) {|methods, method_or_module|
56
+ case method_or_module
57
+ when Symbol, String
58
+ methods << method_or_module.to_sym
59
+ when Module # also includes classes
60
+ methods.concat(method_or_module.instance_methods(include_ancestors))
61
+ when Array
62
+ methods.concat(method_or_module)
63
+ else
64
+ raise ArgumentError, "Bad argument: #{method_or_module.inspect}"
65
+ end
66
+ }
67
+ end
68
+ end
69
+
70
+ def self.clothe(other)
71
+ other.extend(Macros)
72
+ end
73
+
74
+ def self.included(other)
75
+ clothe(other)
76
+ other.singleton_class.extend(Macros)
77
+ end
78
+
79
+ def self.extended(object)
80
+ clothe(object.singleton_class)
81
+ end
82
+ end
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fig_leaf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Avdi Grimm
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-14 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: FigLeaf enables us to selectively make public methods inherited from
15
+ other classes and modules private. The objects can still call these methods internally,
16
+ but external classes are prevented from doing so.
17
+ email:
18
+ - sam@codeodor.com
19
+ executables: []
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - lib/fig_leaf.rb
24
+ homepage: https://github.com/objects-on-rails/fig-leaf
25
+ licenses: []
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ! '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 1.8.8
45
+ signing_key:
46
+ specification_version: 3
47
+ summary: Private inheritance for Ruby classes.
48
+ test_files: []