Почему это ошибка с 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 -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 ')'
2 ответов
если вы посмотрите на код, выдаваемых 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__)
вы можете видеть, что на третьей строке, a do после ). Руби ожидает do...end блок, но получает закрывающую скобку. Это непосредственная причина ошибки.
причина erb outtputting плохой код, что вы используете <%= когда вы должны использовать <%. Изменение кода на this исправляет синтаксис ошибка:
<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 слишком короткий предложил. Я проверил, если erubis аппликации, который Rails 3 используется по умолчанию, ведет себя иначе, чем ERB. Выведенный код by 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, вероятно, не являются проблемой.
Я также попробовал синтаксис-проверка этого фрагмента кода из официальной документации Rails:
<%= form_for(zone) do |f| %>
<p>
<b>Zone name</b><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
он получает ту же ошибку синтаксиса. Так что дело не в том, что ваш код ERB плохо написан; ваш код очень похож к этому примеру.
на данный момент мое лучшее предположение, что erb ' s -x флаг, который переводит шаблон ERB в код Ruby вместо того, чтобы оценивать его напрямую, имеет недостатки и не поддерживает некоторые функции, которые он должен. Хотя теперь, когда я думаю об этом, мне трудно представить, что именно Ruby code должны выводится при выводе результата блока, который сам выводит текст должен работать. В какое время должен быть записан каждый из выходов – сначала результат или содержимое блока?
короткая версия: ничего не случилось; Rails делает некоторые сумасшедшие вещи.
длинная версия: вы можете только сделать
<%= some_method do %>
<% end %>
(то есть, использовать <%= С блоком) из-за гигантского летающего взлома в рельсах. Содержание <%= %> предполагается, что это выражение (или выражения), которое стоит само по себе: вы должны быть в состоянии вставить его в eval и это будет синтаксически правильным.
перед рельсами 3, Люди иногда были смущены тем фактом, что с "нормальными помощниками" (link_to, number_to_currency, etc.), вы должны использовать <%=, но при использовании блочной формы этих помощников или помощников, таких как form_for, вы должны использовать <%. Вот почему Rails 3 сделал <%= поддержка блоков.
для обработки блоков в этом случае, когда вы используете <%=, Rails смотрит на код ERB, видит, выглядит ли он как блок с помощью регулярного выражения, и если он переписывает сгенерированный код на лету, чтобы превратить его в действительный Ruby.
больше кровавые подробности в отличном блоге"блок помощников в Rails 3".