diff options
| author | Paul Kmiec <[email protected]> | 2023-04-29 16:24:22 -0700 |
|---|---|---|
| committer | Paul Kmiec <[email protected]> | 2023-05-15 23:36:40 -0700 |
| commit | a4ba108eb33cba35f87370b7e4b47bff18130e89 (patch) | |
| tree | 3ed38268770453feb0dca6407e4b42c94894f02a /lib/axlsx/util/serialized_attributes.rb | |
| parent | 3b9ac17d8e4dc8b315ac307ffad6f2aa0cb96741 (diff) | |
| download | caxlsx-a4ba108eb33cba35f87370b7e4b47bff18130e89.tar.gz caxlsx-a4ba108eb33cba35f87370b7e4b47bff18130e89.zip | |
Serialize attributes more efficiently
The attributes in rows, cells, styles, etc are pre-defined for each
type and almost never change. The current code, however, does not
take that into account by reading all instance variables (via
declared_attributes), filtering out the blank one and ones that are
not xml attributes, and by camelizing each one.
We can avoid all this extra work by computing the camels and ivars for
xml attributes once and directly read the instance variables we care
about.
Diffstat (limited to 'lib/axlsx/util/serialized_attributes.rb')
| -rw-r--r-- | lib/axlsx/util/serialized_attributes.rb | 53 |
1 files changed, 38 insertions, 15 deletions
diff --git a/lib/axlsx/util/serialized_attributes.rb b/lib/axlsx/util/serialized_attributes.rb index b7247e0d..b2b63fe1 100644 --- a/lib/axlsx/util/serialized_attributes.rb +++ b/lib/axlsx/util/serialized_attributes.rb @@ -15,11 +15,21 @@ module Axlsx # which of the instance values are serializable def serializable_attributes(*symbols) @xml_attributes = symbols + @camel_xml_attributes = nil + @ivar_xml_attributes = nil end # a reader for those attributes attr_reader :xml_attributes + def camel_xml_attributes + @camel_xml_attributes ||= @xml_attributes.map { |attr| Axlsx.camel(attr, false) } + end + + def ivar_xml_attributes + @ivar_xml_attributes ||= @xml_attributes.map { |attr| :"@#{attr}" } + end + # This helper registers the attributes that will be formatted as elements. def serializable_element_attributes(*symbols) @xml_element_attributes = symbols @@ -32,12 +42,12 @@ module Axlsx # creates a XML tag with serialized attributes # @see SerializedAttributes#serialized_attributes def serialized_tag(tagname, str, additional_attributes = {}, &block) - str << "<#{tagname} " + str << '<' << tagname << ' ' serialized_attributes(str, additional_attributes) if block_given? str << '>' yield - str << "</#{tagname}>" + str << '</' << tagname << '>' else str << '/>' end @@ -49,21 +59,34 @@ module Axlsx # serialization to. # @param [Hash] additional_attributes An option key value hash for # defining values that are not serializable attributes list. - def serialized_attributes(str = +'', additional_attributes = {}) - attributes = declared_attributes.merge! additional_attributes - attributes.each do |key, value| - str << "#{Axlsx.camel(key, false)}=\"#{Axlsx.camel(Axlsx.booleanize(value), false)}\" " + # @param [Boolean] camelize_value Should the attribute values be camelized + def serialized_attributes(str = +'', additional_attributes = {}, camelize_value = true) + camel_xml_attributes = self.class.camel_xml_attributes + ivar_xml_attributes = self.class.ivar_xml_attributes + + self.class.xml_attributes.each_with_index do |attr, index| + next if additional_attributes.key?(attr) + next unless instance_variable_defined?(ivar_xml_attributes[index]) + + value = instance_variable_get(ivar_xml_attributes[index]) + next if value.nil? + + value = Axlsx.booleanize(value) + value = Axlsx.camel(value, false) if camelize_value + + str << camel_xml_attributes[index] << '="' << value.to_s << '" ' end - str - end - # A hash of instance variables that have been declared with - # seraialized_attributes and are not nil. - # This requires ruby 1.9.3 or higher - def declared_attributes - Axlsx.instance_values_for(self).select do |key, value| - value != nil && self.class.xml_attributes.include?(key.to_sym) + additional_attributes.each do |attr, value| + next if value.nil? + + value = Axlsx.booleanize(value) + value = Axlsx.camel(value, false) if camelize_value + + str << Axlsx.camel(attr, false) << '="' << value.to_s << '" ' end + + str end # serialized instance values at text nodes on a camelized element of the @@ -82,7 +105,7 @@ module Axlsx value = yield value if block_given? element_name = Axlsx.camel(attribute_name, false) - str << "<#{element_name}>#{value}</#{element_name}>" + str << '<' << element_name << '>' << value << '</' << element_name << '>' end str end |
