4 ms·
Perhaps a better way to implement this would be to use Ruby's string interpolation, which I'm pretty sure allows arbitrary expressions and unlimited levels of n
by extension 16y ago
Perhaps a better way to implement this would be to use Ruby's string interpolation, which I'm pretty sure allows arbitrary expressions and unlimited levels of nesting. For example, this ERB document:
<html>
<%= form_for @stuff do |f| %>
<%= f.text_field :things %>
<% end %>
</html>
would be transformed into this Ruby:
_buffer << "
<html>
#{ form_for @stuff do |f|
_buffer << " #{ f.text_field :things } "
end }
</html>
"
So, ERB goes back to being a very simple transformation with no special cases and you can use any partial syntax in <%= %> blocks that would make sense.
EDIT: Ok, I'm pretty much giving up on this as I can't think of a good enough solution. The two best options I came up with are:
1. Feed the embedded code to Ripper as it comes in and use that to keep track of the lexical context. Ripper is pretty fast so it might not be a significant performance hit, but it only works in Ruby 1.9 and I don't know if a comparable parser for 1.8 exists.
2. Use a setter method like _buf= to append to the output buffer, and don't wrap the embedded expressions in parens. Because the = operator has such low precendence, the generated code will almost always behave as intended, but there are a few lower precendence operators that will break like "and", "or", and postfix "if", "unless", "while" and "until".
- judofyr 16y agoSure, any optimizing template engine would use Ruby's string interpolation, but it would still end up with this: _buffer << "<html> #{ form_for @stuff do |f| } #{ f.text_field :things } #{ end } </html>" How are ERB going to figure out there's an opening of a block unless it actually parses the expression? ERB only sees this: * "<html>" * Output: form_for @stuff do |f| * Output: f.text_field :things * Block: end * "</html>" Just a plain list, not a tree.
- extension 16y agoIndeed, I'm hacking on it now and it seems like there is no way to avoid detecting complete vs incomplete expressions. I guess the question then becomes, can the expressions be classified in a way that is both fast and correct? Let's see if I can find a way.