File tree Expand file tree Collapse file tree 1 file changed +19
-8
lines changed Expand file tree Collapse file tree 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)
2323 Class . new do
2424 attr_reader ( :hash , *fields )
2525
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
2840
29- fields . zip ( values ) do |field , value |
30- instance_variable_set ( :"@#{ field } " , value )
31- end
41+ #{ instance_var_assignments }
3242
33- @hash = self . class . hash ^ values . hash
43+ @hash = self.class.hash ^ values.hash
3444
35- freeze
36- end
45+ freeze
46+ end
47+ RUBY
3748
3849 const_set :VALUE_ATTRS , fields
3950
You can’t perform that action at this time.
0 commit comments