在HAML中映射集合时显示嵌套

时间:2015-09-21 16:18:08

标签: html ruby-on-rails dictionary nested haml

我正在使用HAML开发Rails应用程序。当我偶然发现这种奇怪的行为时,我需要向用户提供一个列表:

显然,此代码不会生成任何输出。

- 5.times.map do |n|
  - n + 1

此代码生成1 2 3 4 5,因为它正在输出内部语句的返回值。

- 5.times.map do |n|
  = n + 1                # Notice the =

此代码生成[1, 2, 3, 4, 5],因为它正在输出映射的数组。

= 5.times.map do |n|     # Notice the =
  - n + 1

到目前为止,非常好......

此代码生成1 2 3 4 5 [0, 0, 0, 0, 0],因为它不像人类。

= 5.times.map do |n|     # Notice the =
  = n + 1                # on both lines

此代码生成1 2 3 4 5 [1, 1, 1, 1, 1],因为它嵌套在<p>

%p                       # Here we are nested one <p> deep
  = 5.times.map do |n|
    = n + 1

此代码生成1 2 3 4 5 [2, 2, 2, 2, 2],因为它是双嵌套的(依此类推)。

%p                       # Here we are nested two <p> deep
  %p
    = 5.times.map do |n|
      = n + 1

有没有人对HAML内部发生的事情有解释? = n+1是否将字符串添加到某个输出缓冲区,然后返回它的嵌套级别?

1 个答案:

答案 0 :(得分:1)

实际上,你所要求的是非常依赖于版本。我的意思是它将在即将推出的Haml版本(v4.1.0)中产生不同的结果。

但首先让我们找出为什么这个版本的输出&lt; 4.1.0

在幕后,Haml将模板转换为可执行的Ruby代码。这项工作在Haml::Compiler课程中完成,您可以轻松地调试此代码:

require 'haml'

puts Haml::Engine.new(%q{
%p
  %p
    %p
      = 5.times.map do |i|
      = i
}).render # => produces the output
          # you have in last example

找出相关的Ruby代码的样子。 通过一些简化,它看起来像这样:

haml_temp =  5.times.map do |i|
  _hamlout.push_text("      #{_hamlout.format_script_false_false_false_false_false_true_false(( i ));}\n", 0, false);
end

您现在可以很容易地看到,您的值已映射到表达式:

_hamlout.push_text(...)

_hamlout这是Haml::Buffer的一个实例,这是last line,它从push_text方法返回值:

 @real_tabs += tab_change

@real_tabs是缩进级别。如果我们不使用缩进,那么它是0,当涉及一个%p时,它变为1,依此类推。 tab_change参数为0(参见调试代码)。

因此,Haml版本4.0.7的输出等于嵌套级别。这正是您的输出的样子。

但这种行为可能会被打破&#34;在即将发布的版本4.1.0中。比较当前主分支的last line of the same method

@buffer << text

将返回一些文字值。