missile_emitter 0.2.0 → 0.3.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: 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