forwarder19 0.2.0rc4 → 0.2.0rc5

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -20,9 +20,7 @@ http://www.opensource.org/licenses/mit-license.html
20
20
 
21
21
  ## Performance
22
22
 
23
- Performance is _normal_, as it is for 'Forwardable' however the goal is to have delegated methods
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
@@ -44,9 +44,9 @@ module Forwarder
44
44
  @params[:to_object]
45
45
  end
46
46
 
47
- def delegatable?
48
- !aop? && !custom_target? && !all? && !chain? && !args && !lambda?
49
- end
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
- set_args_normal if hw
116
- set_args_ary if ha
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
@@ -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
@@ -4,7 +4,6 @@ module Forwarder
4
4
 
5
5
  attr_reader :arguments, :forwardee
6
6
 
7
-
8
7
  # TODO: Break AOP out of this so that we do not check @ runtime
9
8
  def forward
10
9
  if arguments.aop?
@@ -1,3 +1,3 @@
1
1
  module Forwarder
2
- VERSION = '0.2.0rc4'
2
+ VERSION = '0.2.0rc5'
3
3
  end # module Forwarder
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.0rc4
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-21 00:00:00.000000000Z
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: &19218520 !ruby/object:Gem::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: *19218520
24
+ version_requirements: *13783720
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: ruby-debug19
27
- requirement: &19214860 !ruby/object:Gem::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: *19214860
35
+ version_requirements: *13782800
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &19066140 !ruby/object:Gem::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: *19066140
46
+ version_requirements: *13781560
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &18401500 !ruby/object:Gem::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: *18401500
57
+ version_requirements: *13780620
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: maruku
60
- requirement: &18397100 !ruby/object:Gem::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: *18397100
68
+ version_requirements: *13779720
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: wirble
71
- requirement: &18395760 !ruby/object:Gem::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: *18395760
80
- description: ! 'Ruby''s core Forwardable gets the job done(barely) and produces most
81
- unreadable code. Furthermore it is about twice as slow (1.9.2-p290) or thrice as
82
- slow (1.9.3-p0) as it needs to be.
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: []