cannot use frozen object as template binding
stevecrozz opened this issue · comments
Tilt invokes haml compiled methods this way:
https://github.com/rtomayko/tilt/blob/v2.0.1/lib/tilt/template.rb#L155
If scope happens to be a frozen object, the result is a very odd-sounding error:
ERROR -- : NoMethodError: undefined method``upper' for nil:NilClass
This is because an unhandled exception in some dynamically generated source code in Tilt::HamlTemplate#precompiled_preamble
occurs where we attempt to extend the current binding. This could happen for potentially many reasons. In my case the binding (scope) is a frozen object. Since this exception occurs before @haml_buffer
is initialized on the next line, @haml_buffer
remains nil and causes the ensure block in the postamble to fail with essentially nil.upper
I see. So changing it to @haml_buffer = @haml_buffer.upper if @haml_buffer
would at least not hide the real exception?
That's true. I think the error would be TypeError (can't modify frozen object) which probably would have helped me find the error more quickly. I don't suppose there's an easy way to support frozen objects as the binding, is there?
It can be convenient to generate a binding and freeze it before passing it to your view just to make sure nobody modifies it.
Anyway, I'd support making the change you mentioned because like you say at least the error you see will be the real one.
I've fixed the error at least: 1e388db
I'm not sure about removing the extend Haml::Helpers
. I don't enough about how the Haml template is being used.
Closing this since I don't know how to fix it. The Haml maintainers might have a suggestion?