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 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: []