Open ashmaroli opened 4 years ago
This seems to be due to https://github.com/Shopify/liquid/blob/c69a9a77c6a02962a35b377111606576ddb00693/lib/liquid/template.rb#L154-L164
combined with https://github.com/Shopify/liquid/blob/c69a9a77c6a02962a35b377111606576ddb00693/lib/liquid/template.rb#L196-L202
Should probably copy those hashes into the context rather than using them directly.
You can also work around this manually in Ruby by passing a Liquid::Context to render
or with MY_TEMPLATE.assigns.clear
between renders (for all those hashes).
Thank you for responding @pushrax. I currently have a workaround proposed for the downstream project similar to your second suggestion:
@template ||= Liquid::Template.parse(contents, opts)
@template.instance_assigns.clear
@template.render!(*args)
Was waiting for an official comment or workaround from you guys.. If this is not further actionable even for the next major version of Liquid, you may close this ticket.
Should probably copy those hashes into the context rather than using them directly.
I agree. Although, that could mean needing to deeply duplicate the values in those hashes if we want to avoid problems from the value being mutated during rendering.
If conceptually the template is just the result of parsing and rendering shouldn't mutate its state, then it also seems wrong to expose render errors on it through Template#errors. Perhaps we should deprecate that in favour of passing in a context and getting errors from it. Similarly, we should extract the mutable state from ResourceLimits into a separate object to use in the context, so inspecting the final scores would need to be done on the context after rendering.
The source-code documentation suggests caching Liquid templates and using them to render multiple data: https://github.com/Shopify/liquid/blob/0847bf560fbb99d20410408c27d750b7b412d9fa/lib/liquid/template.rb#L9-L10
Fair enough. But if a cached template contains an
assign
tag, rendering it mutates the template's context for subsequent renders.This may be illustrated with the following Ruby script and its output:
Script
Output
Workaround
The workaround is to explicitly reset the assigned variable in an
else
tagBut I feel that the workaround is just a hack and that there shouldn't be a persisting mutation in the first place.