missile_emitter 0.2.0 → 0.3.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: cf6c9f891bd4545da18c8584625c67e4a2e6c7b9c38c3bf162e513c671fbaf0d
4
- data.tar.gz: 5e9b5f13fb874d70ac01c703909990d4388601d537a3bb55ae2d04d10c689931
3
+ metadata.gz: 6f86e582ded328222839a9d72ee7acbd580e90bd1d98ac46da80c2a4a1cd5582
4
+ data.tar.gz: 609969e33ce1b457879f1a45396c378d116f39f06e29b482d28f69970ae716de
5
5
  SHA512:
6
- metadata.gz: f09d6ee53a56dc5eb32d448bec065de6d7f675e5effb397992037df866acce8e676390c52aa1004c606c593d178a57253bb5c79d1b6612fce3c4a47e2c59a5bc
7
- data.tar.gz: 894eca73d7255acd11ceb45f5e916feb77166e0faed9a9a920cf9c0ef4d6bd05b3539f4e2d7937750f4ee9630cbc7e9dac2e69e49a6324de481a25b11a027ce9
6
+ metadata.gz: 167addbf7b4fae490309320664467c40153973d6ec4d7b5b440452b9dd8547db1f15eca2a9716b8921630d518a8bdf5ca60de9d7daf611f8265fa8f6db538bda
7
+ data.tar.gz: eff5ffb62d6885be78f20bc7950321d307ccd038588d0f14cebc6e42ec17872f90225923c9847dd807290815dc2d85dfc92dc462fdcab111e7a86a2116f3e923
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- missile_emitter (0.2.0)
4
+ missile_emitter (0.3.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -102,13 +102,12 @@ me.age # => 36
102
102
 
103
103
  ```ruby
104
104
  module Searchable
105
- # 搜索条件(klass => {keyword: block})
106
- # eg. {Person => {name_like: proc, older_than: proc}}
107
- conditions = {}.with_indifferent_access
105
+ # 搜索条件(klass => {field: scope})
106
+ # eg. {Person => {name_like: scope, older_than: scope}}
107
+ conditions = {}
108
108
 
109
109
  MissileEmitter do |klass, key, *, &block|
110
- conditions[klass] ||= {}
111
- conditions[klass][key] = block
110
+ (conditions[klass] ||= {}.with_indifferent_access)[key] = block
112
111
  end
113
112
 
114
113
  extend ActiveSupport::Concern
@@ -117,15 +116,13 @@ module Searchable
117
116
 
118
117
  define_singleton_method :search do |hash|
119
118
  hash.reduce all do |relation, (key, value)|
120
- # Just for fun :)
121
- relation = relation.extending do
122
- define_method(:_) { value }
123
- end
119
+ next relation if value.blank? # ignore empty value
124
120
 
125
- if value.blank?
126
- relation
127
- elsif filter = conditions.fetch(self, {})[key]
128
- relation.instance_exec(value, &filter)
121
+ if filter = conditions.fetch(self, {})[key]
122
+ relation.extending do
123
+ # Just for fun :)
124
+ define_method(:_) { value }
125
+ end.instance_exec(value, &filter)
129
126
  elsif column_names.include?(key)
130
127
  relation.where key => value
131
128
  else
@@ -151,12 +148,12 @@ end
151
148
  最后,在业务代码中使用:
152
149
 
153
150
  ```ruby
154
- # params: {name: 'Jerry', older_than: 18}
151
+ # params: {name: 'Jerry', older_than: 18, sex: 'male'}
155
152
  Person.search params.slice(:name_like, :older_than, :sex)
156
- # 参数值值不为空的情况下,等价于:
153
+ # 参数值不为空的情况下,等价于:
157
154
  Person.where('name like ?', "%#{params[:name_like]}%")
158
155
  .where('age >= ?', params[:older_than])
159
156
  .where(sex: params[:sex])
160
157
  ```
161
158
 
162
- 总而言之,使用导弹发射器之后,可以很方便的在类定义级别实现声明式DSL,具体怎么用,就留给你自己慢慢挖掘啦。
159
+ 总而言之,使用导弹发射器,可以方便的在类定义级别实现声明式DSL(示例参见 [`attributes.rb`](https://github.com/coding-class-club/missile_emitter/blob/master/lib/missile_emitter/attributes.rb) 、[`searchable.rb`](https://github.com/coding-class-club/missile_emitter/blob/master/lib/missile_emitter/searchable.rb)),至于更多的用法,就留给你自己慢慢挖掘啦。
@@ -18,7 +18,7 @@ module MissileEmitter
18
18
  def exec(namespace, &block)
19
19
  raise Error.new("需要提供代码块") unless block_given?
20
20
 
21
- context = block.binding.eval 'self'
21
+ context = block.binding.receiver
22
22
 
23
23
  raise Error.new("只能再具名模块中调用") unless context.instance_of?(Module) && context.name
24
24
 
@@ -39,10 +39,10 @@ module MissileEmitter
39
39
  container = !ns.empty? && namespace ? constantize(ns) : Kernel
40
40
  action = container == Kernel ? 'define_method' : 'define_singleton_method'
41
41
 
42
- container.send action, name do |&missile|
43
- klass = missile.binding.eval 'self'
42
+ container.send action, name do |*args, &missile|
43
+ klass = missile.binding.receiver
44
44
  battle_field = BattleField.new klass, MissileEmitter.mapping[context]
45
- battle_field.emit! &missile
45
+ battle_field.emit! *args, &missile
46
46
 
47
47
  context
48
48
  end
@@ -87,6 +87,7 @@ module MissileEmitter
87
87
  end
88
88
  end
89
89
  end
90
+
90
91
  end
91
92
 
92
93
  end
@@ -0,0 +1,18 @@
1
+ module MissileEmitter
2
+ module Attributes
3
+ MissileEmitter do |klass, field, default, *, &block|
4
+ attribute = "@#{field}" # 构造实例变量名称,如:name => @name
5
+ # 动态定义实例⽅法
6
+ klass.define_method field do
7
+ if instance_variable_defined?(attribute)
8
+ instance_variable_get attribute
9
+ else
10
+ #返回声明的默认值,同样考虑传递Proc的情况
11
+ block ? instance_eval(&block) : default
12
+ end
13
+ end
14
+ # 写值⽅法
15
+ attr_writer field
16
+ end
17
+ end
18
+ end
@@ -1,12 +1,12 @@
1
1
  module MissileEmitter
2
2
  class BattleField < BasicObject
3
3
 
4
- def initialize(context, callable)
5
- @context, @handler = context, callable
4
+ def initialize(context, *extras, callable)
5
+ @context, @extras, @handler = context, extras, callable
6
6
  end
7
7
 
8
8
  def method_missing(*args, &block)
9
- @handler.call @context, *args, &block
9
+ @handler.call @context, *@extras, *args, &block
10
10
  end
11
11
 
12
12
  alias_method :emit!, :instance_eval
@@ -0,0 +1,34 @@
1
+ module MissileEmitter
2
+ module Searchable
3
+
4
+ # 搜索条件(klass => {field: scope})
5
+ # eg. {Person => {name_like: scope, older_than: scope}}
6
+ conditions = {}
7
+
8
+ MissileEmitter do |klass, key, *, &block|
9
+ (conditions[klass] ||= {}.with_indifferent_access)[key] = block
10
+ end
11
+
12
+ extend ActiveSupport::Concern
13
+
14
+ included do
15
+
16
+ define_singleton_method :search do |hash|
17
+ hash.reduce all do |relation, (key, value)|
18
+ next relation if value.blank? # ignore empty value
19
+
20
+ if filter = conditions.fetch(self, {})[key]
21
+ relation.extending do
22
+ # Just for fun :)
23
+ define_method(:_) { value }
24
+ end.instance_exec(value, &filter)
25
+ elsif column_names.include?(key)
26
+ relation.where key => value
27
+ else
28
+ relation
29
+ end
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -1,3 +1,3 @@
1
1
  module MissileEmitter
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -5,7 +5,7 @@ require "missile_emitter/version"
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "missile_emitter"
7
7
  spec.version = MissileEmitter::VERSION
8
- spec.authors = ["coding-class.com"]
8
+ spec.authors = ["Jerry Chen"]
9
9
  spec.email = ["code@coding-class.com"]
10
10
 
11
11
  spec.summary = %q{Ruby元编程辅助工具}
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.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
- - coding-class.com
7
+ - Jerry Chen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-11-17 00:00:00.000000000 Z
11
+ date: 2019-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -86,7 +86,9 @@ files:
86
86
  - bin/console
87
87
  - bin/setup
88
88
  - lib/missile_emitter.rb
89
+ - lib/missile_emitter/attributes.rb
89
90
  - lib/missile_emitter/battle_field.rb
91
+ - lib/missile_emitter/searchable.rb
90
92
  - lib/missile_emitter/version.rb
91
93
  - missile_emitter.gemspec
92
94
  homepage: https://github.com/coding-class-club/missile_emitter