我正在尝试理解块和yield以及它们在Ruby中的工作方式。
如何使用产量?我研究过的许多Rails应用程序都以一种奇怪的方式使用yield。
谁能给我解释一下或者告诉我怎么理解他们?
我正在尝试理解块和yield以及它们在Ruby中的工作方式。
如何使用产量?我研究过的许多Rails应用程序都以一种奇怪的方式使用yield。
谁能给我解释一下或者告诉我怎么理解他们?
当前回答
我发现这篇文章很有用。特别是下面的例子:
#!/usr/bin/ruby
def test
yield 5
puts "You are in the method test"
yield 100
end
test {|i| puts "You are in the block #{i}"}
test do |i|
puts "You are in the block #{i}"
end
它应该给出以下输出:
You are in the block 5
You are in the method test
You are in the block 100
You are in the block 5
You are in the method test
You are in the block 100
因此,本质上,每次调用yield ruby时,都会运行do块或{}内部的代码。如果提供了一个参数来yield,那么它将作为参数提供给do块。
对我来说,这是我第一次真正理解do模块在做什么。它基本上是函数访问内部数据结构的一种方式,无论是用于迭代还是用于函数配置。
所以在rails中,你可以这样写:
respond_to do |format|
format.html { render template: "my/view", layout: 'my_layout' }
end
This will run the respond_to function which yields the do block with the (internal) format parameter. You then call the .html function on this internal variable which in turn yields the code block to run the render command. Note that .html will only yield if it is the file format requested. (technicality: these functions actually use block.call not yield as you can see from the source but the functionality is essentially the same, see this question for a discussion.) This provides a way for the function to perform some initialisation then take input from the calling code and then carry on processing if required.
或者换句话说,它类似于一个函数以匿名函数作为参数,然后在javascript中调用它。
其他回答
我有时会这样使用yield:
def add_to_http
"http://#{yield}"
end
puts add_to_http { "www.example.com" }
puts add_to_http { "www.victim.com"}
很可能有人会在这里提供一个真正详细的答案,但我一直认为Robert Sosinski的这篇文章对block, procs和lambdas之间的微妙之处进行了很好的解释。
我应该补充一点,我所链接的这篇文章是专门针对ruby 1.8的。ruby 1.9中有一些变化,比如块变量是块的局部变量。在1.8中,你会得到如下内容:
>> a = "Hello"
=> "Hello"
>> 1.times { |a| a = "Goodbye" }
=> 1
>> a
=> "Goodbye"
而1.9会给你:
>> a = "Hello"
=> "Hello"
>> 1.times { |a| a = "Goodbye" }
=> 1
>> a
=> "Hello"
我在这台机器上没有1.9,所以上面可能有一个错误。
我发现这篇文章很有用。特别是下面的例子:
#!/usr/bin/ruby
def test
yield 5
puts "You are in the method test"
yield 100
end
test {|i| puts "You are in the block #{i}"}
test do |i|
puts "You are in the block #{i}"
end
它应该给出以下输出:
You are in the block 5
You are in the method test
You are in the block 100
You are in the block 5
You are in the method test
You are in the block 100
因此,本质上,每次调用yield ruby时,都会运行do块或{}内部的代码。如果提供了一个参数来yield,那么它将作为参数提供给do块。
对我来说,这是我第一次真正理解do模块在做什么。它基本上是函数访问内部数据结构的一种方式,无论是用于迭代还是用于函数配置。
所以在rails中,你可以这样写:
respond_to do |format|
format.html { render template: "my/view", layout: 'my_layout' }
end
This will run the respond_to function which yields the do block with the (internal) format parameter. You then call the .html function on this internal variable which in turn yields the code block to run the render command. Note that .html will only yield if it is the file format requested. (technicality: these functions actually use block.call not yield as you can see from the source but the functionality is essentially the same, see this question for a discussion.) This provides a way for the function to perform some initialisation then take input from the calling code and then carry on processing if required.
或者换句话说,它类似于一个函数以匿名函数作为参数,然后在javascript中调用它。
简单地说,yield允许您创建的方法获取和调用块。yield关键字是块中'stuff'将被执行的位置。
Yield可以用作在方法中返回值的无名块。考虑下面的代码:
Def Up(anarg)
yield(anarg)
end
您可以创建一个方法“Up”,它被分配了一个参数。你现在可以将这个参数赋值给yield,它将调用并执行一个相关的块。您可以在参数列表之后分配块。
Up("Here is a string"){|x| x.reverse!; puts(x)}
当Up方法调用带有参数的yield时,它被传递给块变量以处理请求。