forwarder19 0.2.0rc4 → 0.2.0rc5
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.
- data/README.md +48 -3
- data/lib/forwarder/arguments.rb +19 -9
- data/lib/forwarder/compiler.rb +20 -6
- data/lib/forwarder/meta.rb +0 -1
- data/lib/forwarder/version.rb +1 -1
- metadata +19 -33
data/README.md
CHANGED
@@ -20,9 +20,7 @@ http://www.opensource.org/licenses/mit-license.html
|
|
20
20
|
|
21
21
|
## Performance
|
22
22
|
|
23
|
-
|
24
|
-
to run about as twice as fast as methods created by 'Forwardable.def_delegator'. This seems to be
|
25
|
-
a realistic goal as can be seen here: https://github.com/RobertDober/Forwarder19/blob/dev/bm/study.rb
|
23
|
+
Execution time is that of 85~95% of Forwardable by evalling strings whenever possible.
|
26
24
|
|
27
25
|
|
28
26
|
## Simple Delegation As In Forwardable
|
@@ -95,6 +93,53 @@ one parameter. This becomes clearer with an example.
|
|
95
93
|
with: [ /[,.]\b/, '\& ' ]
|
96
94
|
```
|
97
95
|
|
96
|
+
### A Useful Shorthand
|
97
|
+
|
98
|
+
As I found myself using the following idioms all the time
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
|
102
|
+
forward :some_method, to: :@some_hash, as: :[], with: :some_method
|
103
|
+
forward :other_method, to: :hash, as: :[], with: :other_key
|
104
|
+
|
105
|
+
```
|
106
|
+
|
107
|
+
I conceived the `to_hash` shortcut for these. Strictly spoken (and not striktly spoken
|
108
|
+
too) this is a gross generalisation of the usecase as if they target had to be a `Hash`
|
109
|
+
all the time. This is not the case of course, we are just forwarding a message with a
|
110
|
+
parameter...
|
111
|
+
|
112
|
+
Here is how the above idioms can be expressed by means of the `to_hash` target:
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
|
116
|
+
forward :some_method, to_hash: :@some_hash
|
117
|
+
forward :other_method, to_hash: :hash, as: :other_key
|
118
|
+
|
119
|
+
```
|
120
|
+
|
121
|
+
Concerning jargon we are doing something a little bit confusing here. In all cases we have
|
122
|
+
an implicit translation (which is `:[]` of course). In the second case we have an explicit
|
123
|
+
translation (being `:other_key`) too. The explicit translation is transformed into the first,
|
124
|
+
and only argument, as we do not allow explicit arguments for `to_hash:` targets.
|
125
|
+
|
126
|
+
However you still can use the `forward_all` version and a `to_hash:` chain target, here is
|
127
|
+
an example:
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
|
131
|
+
class Params
|
132
|
+
extend Forwarder
|
133
|
+
forward_all :count, :limit, to_hash: [:@params, :mandatory]
|
134
|
+
forward :pretend?, to_hash: [:@params, :optional], as: :dry_run
|
135
|
+
end
|
136
|
+
|
137
|
+
```
|
138
|
+
|
139
|
+
AOP is not supported for `to_hash:` targets in this version, this might change in the future
|
140
|
+
as use cases are imaginable (e.g. an after filter for the `:pretend?` method, applying !! to
|
141
|
+
the result).
|
142
|
+
|
98
143
|
### Partial Application
|
99
144
|
|
100
145
|
This example gives us the oppurtunity to look at a use case for partial applications. Let us assume that
|
data/lib/forwarder/arguments.rb
CHANGED
@@ -44,9 +44,9 @@ module Forwarder
|
|
44
44
|
@params[:to_object]
|
45
45
|
end
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
# def delegatable?
|
48
|
+
# !aop? && !custom_target? && !all? && !chain? && !args && !lambda?
|
49
|
+
# end
|
50
50
|
|
51
51
|
def evaluable?
|
52
52
|
!lambda? &&
|
@@ -78,6 +78,10 @@ module Forwarder
|
|
78
78
|
Evaller.serialize args
|
79
79
|
end
|
80
80
|
|
81
|
+
def to_hash?
|
82
|
+
@__to_hash__ ||= @params[ :to_hash ]
|
83
|
+
end
|
84
|
+
|
81
85
|
def translation alternative=nil, &blk
|
82
86
|
@params[ :as ].tap do | tltion |
|
83
87
|
break alternative unless tltion
|
@@ -94,7 +98,6 @@ module Forwarder
|
|
94
98
|
def check_for_incompatibilities!
|
95
99
|
raise ArgumentError, "cannot provide translations for forward_all" if @__all__ && translation
|
96
100
|
raise ArgumentError, "cannot provide arguments for forward_all" if @__all__ && args?
|
97
|
-
|
98
101
|
end
|
99
102
|
|
100
103
|
def initialize *args, &blk
|
@@ -105,6 +108,7 @@ module Forwarder
|
|
105
108
|
set_target
|
106
109
|
set_args blk
|
107
110
|
check_for_incompatibilities!
|
111
|
+
translate_to_hash
|
108
112
|
end
|
109
113
|
|
110
114
|
def set_args blk
|
@@ -112,8 +116,10 @@ module Forwarder
|
|
112
116
|
hw = @params.has_key? :with
|
113
117
|
ha = @params.has_key? :with_ary
|
114
118
|
raise ArgumentError, "cannot use :with and :with_ary parameter" if hw && ha
|
115
|
-
|
116
|
-
|
119
|
+
unless to_hash?
|
120
|
+
set_args_normal if hw
|
121
|
+
set_args_ary if ha
|
122
|
+
end
|
117
123
|
end
|
118
124
|
|
119
125
|
def set_args_ary
|
@@ -124,9 +130,9 @@ module Forwarder
|
|
124
130
|
def set_args_normal
|
125
131
|
case arg = @params[:with]
|
126
132
|
when Array
|
127
|
-
@args = arg.dup
|
133
|
+
@args = arg.dup rescue arg
|
128
134
|
else
|
129
|
-
@args = [ arg ]
|
135
|
+
@args = [ (arg.dup rescue arg) ]
|
130
136
|
end
|
131
137
|
end
|
132
138
|
|
@@ -152,7 +158,7 @@ module Forwarder
|
|
152
158
|
end
|
153
159
|
|
154
160
|
def set_target
|
155
|
-
[:to, :to_chain, :to_object].each do | tgt_kwd |
|
161
|
+
[:to, :to_chain, :to_object, :to_hash].each do | tgt_kwd |
|
156
162
|
tgt = @params[ tgt_kwd ]
|
157
163
|
next unless tgt
|
158
164
|
|
@@ -162,6 +168,10 @@ module Forwarder
|
|
162
168
|
raise ArgumentError, "no target specified." unless @target
|
163
169
|
end
|
164
170
|
|
171
|
+
def translate_to_hash
|
172
|
+
return unless @params[:to_hash]
|
173
|
+
raise ArgumentError, "cannot provide arguments for to_hash:" if @params.has_key?( :with ) || @params.has_key?( :with_ary )
|
174
|
+
end
|
165
175
|
def use_block?
|
166
176
|
aop_values.include?( :use_block )
|
167
177
|
end
|
data/lib/forwarder/compiler.rb
CHANGED
@@ -8,6 +8,9 @@ module Forwarder
|
|
8
8
|
# Cannot compile because of intrinsic uncompilable traits of arguments
|
9
9
|
return if arguments.must_not_compile?
|
10
10
|
|
11
|
+
# To Hash can always compile
|
12
|
+
return compile_to_hash if arguments.to_hash?
|
13
|
+
|
11
14
|
# Cannot compile because arguments cannot be compiled
|
12
15
|
@compiled_args = Evaller.serialize arguments.args
|
13
16
|
|
@@ -21,12 +24,6 @@ module Forwarder
|
|
21
24
|
|
22
25
|
private
|
23
26
|
|
24
|
-
def compile_to_all
|
25
|
-
arguments.message.map{ |msg|
|
26
|
-
"def #{msg} *args, &blk; #{arguments.target}.#{msg}( *args, &blk ) end"
|
27
|
-
}.join("\n")
|
28
|
-
end
|
29
|
-
|
30
27
|
def compile_one
|
31
28
|
tltion = arguments.translation arguments.message
|
32
29
|
"def #{arguments.message} *args, &blk; " +
|
@@ -35,6 +32,23 @@ module Forwarder
|
|
35
32
|
"*args, &blk ) end"
|
36
33
|
end
|
37
34
|
|
35
|
+
def compile_to_all
|
36
|
+
arguments.message.map{ |msg|
|
37
|
+
"def #{msg} *args, &blk; #{arguments.target}.#{msg}( *args, &blk ) end"
|
38
|
+
}.join("\n")
|
39
|
+
end
|
40
|
+
|
41
|
+
def compile_to_hash
|
42
|
+
target = arguments.to_hash?
|
43
|
+
target = target.join(".") if Array === target
|
44
|
+
[arguments.message]
|
45
|
+
.flatten
|
46
|
+
.map do | msg |
|
47
|
+
# N.B. that the expression between [] is always a Symbol
|
48
|
+
"def #{msg}; #{target}[ #{(arguments.translation||msg).to_sym.inspect} ] end"
|
49
|
+
end.join("\n")#.tap do |x| debugger end
|
50
|
+
end
|
51
|
+
|
38
52
|
def initialize args
|
39
53
|
@arguments = args
|
40
54
|
end
|
data/lib/forwarder/meta.rb
CHANGED
data/lib/forwarder/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: forwarder19
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.0rc5
|
5
5
|
prerelease: 5
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
12
|
+
date: 2012-04-28 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: lab419_core
|
16
|
-
requirement: &
|
16
|
+
requirement: &13783720 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.0.3
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *13783720
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: ruby-debug19
|
27
|
-
requirement: &
|
27
|
+
requirement: &13782800 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0.11'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *13782800
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rake
|
38
|
-
requirement: &
|
38
|
+
requirement: &13781560 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 0.9.2.2
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *13781560
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rspec
|
49
|
-
requirement: &
|
49
|
+
requirement: &13780620 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 2.9.0
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *13780620
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: maruku
|
60
|
-
requirement: &
|
60
|
+
requirement: &13779720 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 0.6.0
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *13779720
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: wirble
|
71
|
-
requirement: &
|
71
|
+
requirement: &13778460 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,26 +76,12 @@ dependencies:
|
|
76
76
|
version: 0.1.3
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
80
|
-
description: !
|
81
|
-
unreadable code.
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
This is a nonintrusive (as is Forwardable) module that allows to delegate methods
|
86
|
-
to instance variables,
|
87
|
-
|
88
|
-
objects returned by instance_methods, other methods of the same receiver, the receiver
|
89
|
-
itself, a chain of messages or
|
90
|
-
|
91
|
-
an arbitrary object. Paramters can be provided in the forwarding definition (parially
|
92
|
-
or totally=.
|
93
|
-
|
94
|
-
It also defines some AOP support as after and before filters.
|
95
|
-
|
96
|
-
|
97
|
-
Performance will be pushed to 2~3 times of Fowardable with the 0.2 branch of this
|
98
|
-
gem'
|
79
|
+
version_requirements: *13778460
|
80
|
+
description: ! "Ruby's core Forwardable gets the job done(barely) and produces most
|
81
|
+
unreadable code. \n\n Forwarder19 not only is more readable, much more feature
|
82
|
+
rich, but also slightly faster, meaning you can use it without performance penalty.\n\n
|
83
|
+
\ Additional features include: providing arguments, (partially if needed), AOP and
|
84
|
+
custom forwarding to hashes\n "
|
99
85
|
email: robert.dober@gmail.com
|
100
86
|
executables: []
|
101
87
|
extensions: []
|