2017-07-31 22 views
3

在Rails上工作,发现对我对each方法的理解缺乏认识。为什么每个方法都要求它的循环值被分配给一个变量?

不知道为什么each方法需要变量|message|

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

这就是所谓的*迭代*。这就像在Ruby中写任何* loops *一样。 – Pavan

+2

你会如何引用没有变量的当前元素? – Stefan

回答

3

当你循环访问@messages时,需要通过某种方式引用每个元素以使其可用于代码。 Ruby通过将每个元素作为变量一次一个传递给块来做到这一点。在Ruby中使用管道语法来命名任意块上下文中的块变量,而不仅仅是each

Ruby不会自行决定当你在@messages上迭代每个元素应该被称为message。您需要明确地做出该决定,并在管道中分配变量名称。您无需致电变量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 %> 
+1

如果你知道你有一个参数,你可以逃避不定义它,有几个(有点复杂)的情况。 #1如果参数是一个块,你可以用'yield'来调用这个块,而不是为它定义一个变量。 #2你可以使用'&:something'的情况,但是那些代码实际上并不是代码块,即使它们编译为一个。总之尽管你的帖子完全回答了问题+1。 –

7

不知道为什么每个方法需要变量|message|

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

<% @messages.each do %> 

但是,在这种情况下,你打算在你的<h2>输出什么?

1

each不会在块VS外面改变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],这里)

相关问题