modulation 0.20 → 0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e540dd13f308e46a50219db2bafb9b72c692dfc04a43404dcddc85c6117c5f7b
4
- data.tar.gz: 64de165287b53651385fb6e520f15d493e360599afb85c90ca90b91af1aa49e8
3
+ metadata.gz: 1d5bf725c036d3db2d9604cd161f6742c669c392ed09bdeb315a39fd343d4887
4
+ data.tar.gz: 655000532ad754fd550b913a38cc92adc790761d5b98b6b64a91ad9d1ec61664
5
5
  SHA512:
6
- metadata.gz: 3b36c16543e39b4f00afe5129e80f430b56f757258b49785c7a22b6abed52896951b43a6fdc97397807bc95da188829622ff398dfbdcf7ea0e48e701aaa4ece6
7
- data.tar.gz: ff3a3c843a5c2f5e2401fb55c16f19b39281d05acf71c4e1a9d5b7838e7de571be4c4e41657db438724709c768909a077a43d3aaac826689fa485c2ac05a65c3
6
+ metadata.gz: f50f8030beb0e9f009735763c183623f20869ff78f10ac592b2ce1d5de11f1168d8f64576801d117e7337f1cdc8d80845db70ede5f090480437f06a42d328e54
7
+ data.tar.gz: 437c524656fc62ee887ddf69e2a011b5984cd796bfeb0568afdd31296392930525a3752f200d2175deec41b6bbeceef308f0a8bd50609a8ef562f118e2296e1f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ 0.21 2019-02-19
2
+ ---------------
3
+
4
+ * Add support for list of symbols to import in `Kernel#include_from`
5
+
1
6
  0.20 2019-01-16
2
7
  ---------------
3
8
 
data/README.md CHANGED
@@ -205,6 +205,16 @@ end
205
205
  5.seq(:fib)
206
206
  ```
207
207
 
208
+ The `include_from` method accepts an optional list of symbols to import:
209
+
210
+ ```ruby
211
+ class Integer
212
+ include_from './seq.rb', :fib
213
+ end
214
+
215
+ 5.fib
216
+ ```
217
+
208
218
  ### Default exports
209
219
 
210
220
  A module may wish to expose just a single class or constant, in which case it
@@ -56,6 +56,59 @@ module Modulation
56
56
  end
57
57
  end
58
58
 
59
+ # Adds all or part of a module's methods to a target object
60
+ # If no symbols are given, all methods are added
61
+ # @param mod [Module] imported module
62
+ # @param target [Object] object to add methods to
63
+ # @param symbols [Array<Symbol>] list of methods to add
64
+ # @return [void]
65
+ def add_module_methods(mod, target, *symbols)
66
+ methods = mod.singleton_class.instance_methods(false)
67
+ unless symbols.empty?
68
+ not_exported = symbols.select { |s| s =~ /^[a-z]/ } - methods
69
+ unless not_exported.empty?
70
+ raise NameError, "symbol #{not_exported.first.inspect} not exported"
71
+ end
72
+ methods = methods & symbols
73
+ end
74
+ methods.each do |sym|
75
+ target.send(:define_method, sym, &mod.method(sym))
76
+ end
77
+ end
78
+
79
+ # Adds all or part of a module's constants to a target object
80
+ # If no symbols are given, all constants are added
81
+ # @param mod [Module] imported module
82
+ # @param target [Object] object to add constants to
83
+ # @param symbols [Array<Symbol>] list of constants to add
84
+ # @return [void]
85
+ def add_module_constants(mod, target, *symbols)
86
+ exported = mod.__module_info[:exported_symbols]
87
+ unless symbols.empty?
88
+ not_exported = symbols.select { |s| s =~ /^[A-Z]/ } - exported
89
+ unless not_exported.empty?
90
+ raise NameError, "symbol #{not_exported.first.inspect} not exported"
91
+ end
92
+ exported = exported & symbols
93
+ end
94
+ mod.singleton_class.constants(false).each do |sym|
95
+ next unless exported.include?(sym)
96
+ target.const_set(sym, mod.singleton_class.const_get(sym))
97
+ end
98
+ end
99
+
100
+ # Defines a const_missing method used for auto-importing on a given object
101
+ # @param receiver [Object] object to receive the const_missing method call
102
+ # @param auto_import_hash [Hash] a hash mapping constant names to a source
103
+ # file and a caller location
104
+ # @return [void]
105
+ def define_auto_import_const_missing_method(receiver, auto_import_hash)
106
+ receiver.singleton_class.define_method(:const_missing) do |sym|
107
+ (path, caller_location) = auto_import_hash[sym]
108
+ path ? const_set(sym, import(path, caller_location)) : super
109
+ end
110
+ end
111
+
59
112
  # Creates a new module from a source file
60
113
  # @param path [String] source file name
61
114
  # @return [Module] module
@@ -28,7 +28,10 @@ class Module
28
28
  def auto_import(sym, path = nil, caller_location = caller(1..1).first)
29
29
  unless @__auto_import_registry
30
30
  a = @__auto_import_registry = {}
31
- define_auto_import_const_missing_method(@__auto_import_registry)
31
+ Modulation.define_auto_import_const_missing_method(
32
+ self,
33
+ @__auto_import_registry
34
+ )
32
35
  end
33
36
  if path
34
37
  @__auto_import_registry[sym] = [path, caller_location]
@@ -42,40 +45,18 @@ class Module
42
45
  # @return [void]
43
46
  def extend_from(path)
44
47
  mod = import(path, caller(1..1).first)
45
- add_module_methods(mod, self.class)
46
- add_module_constants(mod, self)
48
+ Modulation.add_module_methods(mod, self.class)
49
+ Modulation.add_module_constants(mod, self)
47
50
  end
48
51
 
49
52
  # Includes exported methods from the given file name in the receiver
50
53
  # The module's methods will be available as instance methods
51
54
  # @param path [String] module filename
55
+ # @param symbols [Array<Symbol>] list of symbols to include
52
56
  # @return [void]
53
- def include_from(path)
57
+ def include_from(path, *symbols)
54
58
  mod = import(path, caller(1..1).first)
55
- add_module_methods(mod, self)
56
- add_module_constants(mod, self)
57
- end
58
-
59
- private
60
-
61
- def define_auto_import_const_missing_method(auto_import_hash)
62
- singleton_class.define_method(:const_missing) do |sym|
63
- (path, caller_location) = auto_import_hash[sym]
64
- path ? const_set(sym, import(path, caller_location)) : super
65
- end
66
- end
67
-
68
- def add_module_methods(mod, target)
69
- mod.singleton_class.instance_methods(false).each do |sym|
70
- target.send(:define_method, sym, &mod.method(sym))
71
- end
72
- end
73
-
74
- def add_module_constants(mod, target)
75
- exported_symbols = mod.__module_info[:exported_symbols]
76
- mod.singleton_class.constants(false).each do |sym|
77
- next unless exported_symbols.include?(sym)
78
- target.const_set(sym, mod.singleton_class.const_get(sym))
79
- end
59
+ Modulation.add_module_methods(mod, self, *symbols)
60
+ Modulation.add_module_constants(mod, self, *symbols)
80
61
  end
81
62
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Modulation
4
- VERSION = '0.20'
4
+ VERSION = '0.21'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modulation
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.20'
4
+ version: '0.21'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-16 00:00:00.000000000 Z
11
+ date: 2019-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest