missile_emitter 0.1.3 → 0.2.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
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