missile_emitter 0.1.3 → 0.2.0

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: 534af4ac4601f588ea739fbd20ceb843c5ecccab0864733b39f80344c17e6e9d
4
- data.tar.gz: be3f81c1b23d493a13c219ecb70e2c66c3cc501ac3c268231c5b6a6372ce5ef9
3
+ metadata.gz: cf6c9f891bd4545da18c8584625c67e4a2e6c7b9c38c3bf162e513c671fbaf0d
4
+ data.tar.gz: 5e9b5f13fb874d70ac01c703909990d4388601d537a3bb55ae2d04d10c689931
5
5
  SHA512:
6
- metadata.gz: 15f74d0293c583e261b7f5341e4d5a15508b6e5816371730c5378e65b74dbc16e83f17c28e1aedb5da11c7374a2dc31e3d4e53cecf06d33afbd5beb1a7dbcb25
7
- data.tar.gz: cdb05494493b6b8bd9134a5e0b5cd531dc67c1750d129771c46fe69787424298f5b82cabd04c070354eb1fdb5bbba2d48ea5cbf4d024dea01c384f0c89ece614
6
+ metadata.gz: f09d6ee53a56dc5eb32d448bec065de6d7f675e5effb397992037df866acce8e676390c52aa1004c606c593d178a57253bb5c79d1b6612fce3c4a47e2c59a5bc
7
+ data.tar.gz: 894eca73d7255acd11ceb45f5e916feb77166e0faed9a9a920cf9c0ef4d6bd05b3539f4e2d7937750f4ee9630cbc7e9dac2e69e49a6324de481a25b11a027ce9
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- missile_emitter (0.1.2)
4
+ missile_emitter (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -1,3 +1,3 @@
1
1
  module MissileEmitter
2
- VERSION = "0.1.3"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -15,23 +15,31 @@ module MissileEmitter
15
15
  class << self
16
16
  attr_accessor :mapping
17
17
 
18
- def exec(&block)
18
+ def exec(namespace, &block)
19
19
  raise Error.new("需要提供代码块") unless block_given?
20
20
 
21
21
  context = block.binding.eval 'self'
22
22
 
23
23
  raise Error.new("只能再具名模块中调用") unless context.instance_of?(Module) && context.name
24
24
 
25
- mimic_method context
25
+ mimic_method context, namespace: namespace
26
26
 
27
27
  mapping[context] = block
28
28
  end
29
29
 
30
30
  private
31
31
 
32
- def mimic_method(context)
33
- # TODO:处理多层命名空间的情况
34
- Kernel.define_method context.name do |&missile|
32
+ def mimic_method(context, namespace: true)
33
+ path = context.name
34
+
35
+ ns = deconstantize path
36
+ name = demodulize path
37
+
38
+ # 处理嵌套模块
39
+ container = !ns.empty? && namespace ? constantize(ns) : Kernel
40
+ action = container == Kernel ? 'define_method' : 'define_singleton_method'
41
+
42
+ container.send action, name do |&missile|
35
43
  klass = missile.binding.eval 'self'
36
44
  battle_field = BattleField.new klass, MissileEmitter.mapping[context]
37
45
  battle_field.emit! &missile
@@ -39,12 +47,52 @@ module MissileEmitter
39
47
  context
40
48
  end
41
49
  end
50
+
51
+ def demodulize(path)
52
+ path = path.to_s
53
+
54
+ if i = path.rindex("::")
55
+ path[(i + 2)..-1]
56
+ else
57
+ path
58
+ end
59
+ end
60
+
61
+ def deconstantize(path)
62
+ path.to_s[0, path.rindex("::") || 0]
63
+ end
64
+
65
+ def constantize(camel_cased_word)
66
+ names = camel_cased_word.split("::")
67
+
68
+ Object.const_get(camel_cased_word) if names.empty?
69
+
70
+ names.shift if names.size > 1 && names.first.empty?
71
+
72
+ names.inject(Object) do |constant, name|
73
+ if constant == Object
74
+ constant.const_get(name)
75
+ else
76
+ candidate = constant.const_get(name)
77
+ next candidate if constant.const_defined?(name, false)
78
+ next candidate unless Object.const_defined?(name)
79
+
80
+ constant = constant.ancestors.inject(constant) do |const, ancestor|
81
+ break const if ancestor == Object
82
+ break ancestor if ancestor.const_defined?(name, false)
83
+ const
84
+ end
85
+
86
+ constant.const_get(name, false)
87
+ end
88
+ end
89
+ end
42
90
  end
43
91
 
44
92
  end
45
93
 
46
94
  module Kernel
47
- def MissileEmitter(&block)
48
- MissileEmitter.exec &block
95
+ def MissileEmitter(namespace: true, &block)
96
+ MissileEmitter.exec namespace, &block
49
97
  end
50
98
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: missile_emitter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - coding-class.com
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-11-16 00:00:00.000000000 Z
11
+ date: 2019-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler