From cea706a318b72ff7315cbb94a9e495395318fb06 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 30 Oct 2018 11:18:47 +0000 Subject: [PATCH] Avoid metaprogramming when bulk setting attributes. We extract key normalisation from `method_missing` so we can use it in `[]=`, so that `attributes=` does not have to go through `method_missing` to get to `set_attribute`. On my local this yields a ~20% decrease in deserialization time. --- .../helpers/dynamic_attributes.rb | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/json_api_client/helpers/dynamic_attributes.rb b/lib/json_api_client/helpers/dynamic_attributes.rb index ba827c5..b7ec8f2 100644 --- a/lib/json_api_client/helpers/dynamic_attributes.rb +++ b/lib/json_api_client/helpers/dynamic_attributes.rb @@ -11,7 +11,7 @@ def attributes=(attrs = {}) return @attributes unless attrs.present? attrs.each do |key, value| - send("#{key}=", value) + self[key] = value end end @@ -20,7 +20,8 @@ def [](key) end def []=(key, value) - set_attribute(key, value) + normalized_key = normalize_name(key) + set_attribute(normalized_key, value) end def respond_to_missing?(method, include_private = false) @@ -37,12 +38,16 @@ def has_attribute?(attr_name) protected + def normalize_name(name) + if key_formatter + key_formatter.unformat(name.to_s) + else + name.to_s + end + end + def method_missing(method, *args, &block) - normalized_method = if key_formatter - key_formatter.unformat(method.to_s) - else - method.to_s - end + normalized_method = normalize_name(method) if normalized_method =~ /^(.*)=$/ set_attribute($1, args.first)