<div class='row'>
  <%= form.field_container :name do %>
    <%= form.label :name, raw('Name' + content_tag(:span, ' *', :class => 'required')) %>
    <%= form.text_field :name, :class => 'fullwidth' %>
    <%= form.error_message_on :name %>
  <% end %>
</div>

为什么会产生以下错误?
$ erb -x -T - test.erb | ruby -c
-:3: syntax error, unexpected ')'
...form.field_container :name do ).to_s); _erbout.concat "\n"
...                               ^
-:9: syntax error, unexpected $end, expecting ')'

最佳答案

如果查看erb -x -T - test.erb输出的代码:

#coding:ASCII-8BIT
_erbout = ''; _erbout.concat "<div class='row'>\n  "
; _erbout.concat(( form.field_container :name do ).to_s); _erbout.concat "\n"
; _erbout.concat "    "; _erbout.concat(( form.label :name, raw('Name' + content_tag(:span, ' *', :class => 'required')) ).to_s); _erbout.concat "\n"
; _erbout.concat "    "; _erbout.concat(( form.text_field :name, :class => 'fullwidth' ).to_s); _erbout.concat "\n"
; _erbout.concat "    "; _erbout.concat(( form.error_message_on :name ).to_s); _erbout.concat "\n"
; _erbout.concat "  ";  end ; _erbout.concat "\n"
; _erbout.concat "</div>\n"
; _erbout.force_encoding(__ENCODING__)

您可以在第三行看到do后跟一个)。 Ruby期望使用doend块,但括号括起来。这是语法错误的直接原因。
erb胜过错误代码的原因是,当您应该使用<%=时,您正在使用<%。将您的代码更改为此可修复语法错误:

<div class='row'>
  <% form.field_container :name do %>
    <%= form.label :name, raw('Name' + content_tag(:span, ' *', :class => 'required')) %>
    <%= form.text_field :name, :class => 'fullwidth' %>
    <%= form.error_message_on :name %>
  <% end %>
</div>

我无法运行此代码来测试更改后是否输出了应该输出的内容,但是erb生成的代码看起来可以正常工作:

#coding:ASCII-8BIT
_erbout = ''; _erbout.concat "<div class='row'>\n  "
;  form.field_container :name do ; _erbout.concat "\n"
; _erbout.concat "    "; _erbout.concat(( form.label :name, raw('Name' + content_tag(:span, ' *', :class => 'required')) ).to_s); _erbout.concat "\n"
# more...

编辑

由于此解决方案显然会破坏输出,因此我研究了mu is too short的建议。我检查了Erubis(即Rails 3 uses by default)的行为是否不同于ERB。 erubis -x -T - test.erb输出的代码(带有未经编辑的原始test.erb):

_buf = ''; _buf << '<div class=\'row\'>
  '; _buf << ( form.field_container :name do ).to_s; _buf << '
'; _buf << '    '; _buf << ( form.label :name, raw('Name' + content_tag(:span, ' *', :class => 'required')) ).to_s; _buf << '
'; _buf << '    '; _buf << ( form.text_field :name, :class => 'fullwidth' ).to_s; _buf << '
'; _buf << '    '; _buf << ( form.error_message_on :name ).to_s; _buf << '
';   end
 _buf << '</div>
';
_buf.to_s

第三行有完全相同的问题,并且erubis -x -T - test.erb | ruby -c输出相同的语法错误。因此,ERB和Erubis之间的差异可能不是问题。

我还尝试了语法检查这段代码from the official Rails documentation:

<%= form_for(zone) do |f| %>
  <p>
    <b>Zone name</b><br />
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.submit %>
  </p>
<% end %>

它得到相同的语法错误。因此,这并不是说您的ERB代码写得不好。您的代码与该示例非常相似。

目前,我最好的猜测是erb-x标志存在缺陷,并且不支持应有的某些功能,该标志将ERB模板转换为Ruby代码而不是直接对其进行评估。尽管现在考虑了一下,但是当您输出本身可以输出文本的块的结果时,我很难想象要输出什么Ruby代码。每个输出应该在什么时间写入?首先输出结果,还是首先写入块内容?

关于ruby - 为什么这是ERB的错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17374274/

10-13 04:44