为什么每个方法都需要将循环的值分配给变量?

时间:2017-07-31 12:25:26

标签: ruby-on-rails ruby

使用Rails,发现我对each方法的理解缺乏了解。

不确定为什么each方法需要变量|message|

<% @messages.each do |message| %>
    <h2><%= message.title %></h2>
    <%= link_to "View Message", message_path(message), class: "btn btn-default" %>
<% end %>

3 个答案:

答案 0 :(得分:7)

  

不确定为什么每个方法都需要变量|message|

它不要求它。你可以很好地省略它。

<% @messages.each do %>

但是,在这种情况下,您要在<h2>中输出什么?

答案 1 :(得分:3)

当您遍历@messages时,需要某种方式来引用每个元素以使其可用于您的代码。 Ruby通过将每个元素一次作为变量传递给块来完成此操作。管道语法在Ruby中用于命名任何块上下文中的块变量,而不仅仅是each

当你在@messages上迭代每个元素应该被称为message时,Ruby不会自己决定。您需要明确地做出该决定并在管道中分配变量名称。您不需要调用变量message。你可以称之为hot_dog。但是你需要将元素分配给某些东西,否则你将无法访问它以及循环的重点是什么?

<% @messages.each do |hot_dog| %>
    <h2><%= hot_dog.title %></h2>
    <%= link_to "View Message", message_path(hot_dog), class: "btn btn-default" %>
<% end %>

答案 2 :(得分:1)

each不会更改块中self的值与其之外的值。例如:

class Foo
  def bar1; "hello"; end
  def bar2; [1].each { puts bar1 }
end
Foo.new.bar2 # => "hello"

在此示例中,bar1方法调用与说puts self.bar1相同,因此您需要在块外保持self的相同值。

如果要将块中的self的值设置为当前的iteratee,可以使用如下方法:

def bound_each(&blk)
  each { |x| x.instance_eval &blk }
end
[1].bound_each { puts self } # => 1

然而,据我所知,没有像Ruby或Rails核心这样的内容。

另请参阅https://stackoverflow.com/a/45556401/2981429,了解将self与可枚举([1],此处)绑定的类似方法