File tree 1 file changed +19
-8
lines changed 1 file changed +19
-8
lines changed Original file line number Diff line number Diff line change @@ -23,17 +23,28 @@ def self.new(*fields, &block)
23
23
Class . new do
24
24
attr_reader ( :hash , *fields )
25
25
26
- define_method ( :initialize ) do |*values |
27
- raise ArgumentError . new ( "wrong number of arguments, #{ values . size } for #{ fields . size } " ) if fields . size != values . size
26
+ # Unroll the fields into a series of assignment Ruby statements that can
27
+ # be used inside of the initializer for the new class. This was introduced
28
+ # in PR#56 as a performance optimization -- it ensures that this iteration
29
+ # happens once per class, instead of happening once per instance of the
30
+ # class.
31
+ instance_var_assignments = Array . new ( fields . length ) do |idx |
32
+ "@#{ fields [ idx ] } = values[#{ idx } ]"
33
+ end . join ( "\n " )
34
+
35
+ class_eval <<-RUBY
36
+ def initialize(*values)
37
+ if #{ fields . size } != values.size
38
+ raise ArgumentError.new("wrong number of arguments, \# {values.size} for #{ fields . size } ")
39
+ end
28
40
29
- fields . zip ( values ) do |field , value |
30
- instance_variable_set ( :"@#{ field } " , value )
31
- end
41
+ #{ instance_var_assignments }
32
42
33
- @hash = self . class . hash ^ values . hash
43
+ @hash = self.class.hash ^ values.hash
34
44
35
- freeze
36
- end
45
+ freeze
46
+ end
47
+ RUBY
37
48
38
49
const_set :VALUE_ATTRS , fields
39
50
You can’t perform that action at this time.
0 commit comments