在Rails中,“respond_to do |x| .. end”是什么Ruby语言结构?

3

我刚接触Ruby和Rails。有人能告诉我下面这个结构是什么吗?我在方法(def)中看到respond_to结构。所以它是一个嵌套的方法吗?我的意思是,我试图理解这个语言结构。

我确实理解它的功能,即按照给定格式发送响应。

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @posts }
    end

它(respond_to)是一个被传递了块(关键字!)的方法。此外,应该是end而不是ends - user166390
那么它就像一个自执行的方法吗? - murtaza52
2
respond_to方法决定如何调用块(使用yield)。例如,对于空数组来说,Array.each将不会执行任何操作。块类似于匿名函数,在JavaScript中通常被广泛使用。然而,它们并不是一等值(在方法内部可以通过使用&block语法,通过Proc来提升/推广块)。 - user166390
谢谢。您能将其发布为答案吗?我会标记它为已回答。 - murtaza52
它真的值得更多关注,比如一个或两个链接。我今晚会跳过,但它会得到一些喜爱 :) - user166390
http://www.robertsosinski.com/2008/12/21/understanding-ruby-blocks-procs-and-lambdas/ - murtaza52
3个回答

3

这个语言结构是Ruby块。但是如果你真的想了解respond_to,这篇博客文章提供了一个很好的概述。

respond_to如何工作?

关键的事情在于,respond_to是附加在控制器的超类ActionController上的方法,并且我们将一个叫做块的东西作为参数传递:

...

respond_to方法内部,我们最终得到一个接受一个参数的Proc。该参数在其上调用了.xml和.html方法。当我们从respond_to内部调用该Proc时,我们将Responder类的实例作为参数传递给它。

因此,我们最终会在传递给respond_to内部(转换为Proc的)块中调用Responder类的实例上的.html和.xml方法... 呼。


所以,HTML和JSON方法都是在响应器(格式)类的实例上调用的。这是否意味着Rails将为这两种情况返回响应? - murtaza52
是的,如果您使用website/book.js调用它,Rails会返回JSON;如果您使用website/book.html调用它,则会返回HTML。 - Dty

2

这是闭包。它类似于在其他语言中将函数传递给函数,例如,在Ruby中,您有两个选项来迭代集合:

for elem in collection
  # do something
end

或者

collection.each do |elem|
  # do something
end

这两者之间有区别,但我不会在这里描述。所以,正如你所看到的那样,它就像将函数传递给方法并在其中运行一样。但是,有两种方法来传递 block,使用 do |variables| ... end 块或 { |variables| ... } 块。如果你想编写自己的方法接受 block,也有多种方法可以做到(它们有点不同,但运行方式相同):

def run_3_times
  yield
  yield
  yield
end

或者

def run_3_times(&block)
  block.call
  block.call
  block.call
end

它们都被称为相同的方式:

run_3_times { puts 'hello' }
# will yield
hello
hello
hello

但是当没有传递块时,这将导致另一个错误:

# when using yield
LocalJumpError: no block given (yield)

# when using Proc.call
NoMethodError: undefined method `call' for nil:NilClass
from (pry):8:in `run_3_times'

这里有一些关于it技术的文章:

请注意,本文档的翻译可能存在一定偏差,仅供参考。

因为 for ... in 不会引入新的作用域。 - Hauleth

-1
在Ruby中,.respond_to?是一个测试方法。它的作用之一是接受一个符号,并返回一个true(如果对象可以接收一个方法)或false(如果不能接收一个方法)。例如:
[1, 2, 3].respond_to?(:push) 会返回true,因为你可以在数组对象上调用.push方法。但是, [1, 2, 3].respond_to?(:to_sym) 会返回false,因为你不能将一个数组转换成一个符号。
链接:
a] Ruby是面向方法调用答案的,而不是面向对象类型的。 respond_to?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接