在 rspec 上下文中解释 procs 的用法
Explain the usage of procs in an rspec context
这是一个使用自定义 RSpec 匹配器的期望,yield_variables:
specify { expect{ |p| [3,4,5].my_each(&p) }.to yield_variables [3,4,5] }
我的 yield_variables 匹配器的匹配项?方法使用一个名为 Probe 的自定义 class(Probe 是 RSpec 的 yield probe 的精简版):
...
def matches? block
ap Probe.probe block
# note i am inspecting what is returned by Probe.probe with ap
end
...
# Probe class is what all my questions are about!
class Probe
attr_accessor :yielded_args
def initialize
self.yielded_args = []
end
def self.probe(block)
probe = new
block.call(probe)
probe.yielded_args
end
def to_proc
Proc.new { |*args| yielded_args << args }
end
end
现在我的 ap inside matches?
报告:[3,4,5]
这就是我所期望的。但是,我不知道探测器 class 是如何工作的!!
问题 1) 火柴?区块
通常情况下,我们传递给匹配的参数?是我们期望的主题return。即,我希望 [3,4,5]
被传递到块中。
相反,|p| [3,4,5].my_each(&p)
作为 proc 传递到块中。这是为什么?
问题2)block.call(探查)
我对 proc 有点不太了解所以请慢慢解释。但基本上,这里我们采用我的 Probe class 和 'send' 块的新实例作为参数。这就是我尽力解释的方式,但我可能完全错了,所以请慢慢解释。
问题3)to_proc是怎么调用的?
.to_proc 到底是怎么自动调用的?我相信它是由 block.call(probe) 自动调用的。 to_proc是和initialize一样自动调用的方法吗?每当将 class 发送到 proc 时,它会自动调用吗? (顺便说一句, class 被发送到 proc 的短语对我来说甚至没有 100% 的意义 - 请解释。该块不再作为参数传递到 class 中。或者如果该块作为参数传递 block.call 语法感觉真的很奇怪和倒退)
问题4)to_proc
to_proc 如何访问期望的主题,即 |p| [3,4,5].my_each(&p)
? Proc.new 的 *args 如何自动填充每个可能的 yield 参数,即使我只传入了 |p| ? Proc.new 如何与我的 my_each 一起循环,将我所有的参数递增地放入数组中? Proc.new 如何了解主题 |p| [3,4,5].my_each(&p)
?如何??请解释,谢谢。
基于块的行进器与其他匹配器的工作方式略有不同。通常,如果对您感兴趣的表达式进行求值并将结果传递给您,您想做一些不可能的事情。
例如,raises_error
匹配器想要执行块本身以查看是否引发了正确的异常,而 change
匹配器想要在前后评估其他表达式以查看它是否更改以指定的方式。这就是为什么向您传递的是块而不是值。
您传递给 expect
的块采用 1 个参数并将其用作对 my_each
的调用中的块,因此当您的 Probe.probe 方法调用该块时,它必须传递一些东西作为价值。您已经表述为 "sending the block to the probe instance" 但它是另一种方式:使用 probe 作为参数调用该块。
块执行并调用my_each
。这里 p
是 Probe
的实例。在参数前加上 & 告诉 ruby 这个参数应该用作方法的块(方法是 my_each)。如果参数还不是 proc ruby 调用 to_proc
。这就是 Probe#to_proc 的调用方式
假设 my_each
的行为与正常的 each
相似,它将调用它的块(即 to_proc
的 return 值)一次数组中的值。
通常情况下,您的匹配器会将 Probe.probe
中的 return 值与实际值进行比较。
这是一个使用自定义 RSpec 匹配器的期望,yield_variables:
specify { expect{ |p| [3,4,5].my_each(&p) }.to yield_variables [3,4,5] }
我的 yield_variables 匹配器的匹配项?方法使用一个名为 Probe 的自定义 class(Probe 是 RSpec 的 yield probe 的精简版):
...
def matches? block
ap Probe.probe block
# note i am inspecting what is returned by Probe.probe with ap
end
...
# Probe class is what all my questions are about!
class Probe
attr_accessor :yielded_args
def initialize
self.yielded_args = []
end
def self.probe(block)
probe = new
block.call(probe)
probe.yielded_args
end
def to_proc
Proc.new { |*args| yielded_args << args }
end
end
现在我的 ap inside matches?
报告:[3,4,5]
这就是我所期望的。但是,我不知道探测器 class 是如何工作的!!
问题 1) 火柴?区块
通常情况下,我们传递给匹配的参数?是我们期望的主题return。即,我希望 [3,4,5]
被传递到块中。
相反,|p| [3,4,5].my_each(&p)
作为 proc 传递到块中。这是为什么?
问题2)block.call(探查)
我对 proc 有点不太了解所以请慢慢解释。但基本上,这里我们采用我的 Probe class 和 'send' 块的新实例作为参数。这就是我尽力解释的方式,但我可能完全错了,所以请慢慢解释。
问题3)to_proc是怎么调用的?
.to_proc 到底是怎么自动调用的?我相信它是由 block.call(probe) 自动调用的。 to_proc是和initialize一样自动调用的方法吗?每当将 class 发送到 proc 时,它会自动调用吗? (顺便说一句, class 被发送到 proc 的短语对我来说甚至没有 100% 的意义 - 请解释。该块不再作为参数传递到 class 中。或者如果该块作为参数传递 block.call 语法感觉真的很奇怪和倒退)
问题4)to_proc
to_proc 如何访问期望的主题,即 |p| [3,4,5].my_each(&p)
? Proc.new 的 *args 如何自动填充每个可能的 yield 参数,即使我只传入了 |p| ? Proc.new 如何与我的 my_each 一起循环,将我所有的参数递增地放入数组中? Proc.new 如何了解主题 |p| [3,4,5].my_each(&p)
?如何??请解释,谢谢。
基于块的行进器与其他匹配器的工作方式略有不同。通常,如果对您感兴趣的表达式进行求值并将结果传递给您,您想做一些不可能的事情。
例如,raises_error
匹配器想要执行块本身以查看是否引发了正确的异常,而 change
匹配器想要在前后评估其他表达式以查看它是否更改以指定的方式。这就是为什么向您传递的是块而不是值。
您传递给 expect
的块采用 1 个参数并将其用作对 my_each
的调用中的块,因此当您的 Probe.probe 方法调用该块时,它必须传递一些东西作为价值。您已经表述为 "sending the block to the probe instance" 但它是另一种方式:使用 probe 作为参数调用该块。
块执行并调用my_each
。这里 p
是 Probe
的实例。在参数前加上 & 告诉 ruby 这个参数应该用作方法的块(方法是 my_each)。如果参数还不是 proc ruby 调用 to_proc
。这就是 Probe#to_proc 的调用方式
假设 my_each
的行为与正常的 each
相似,它将调用它的块(即 to_proc
的 return 值)一次数组中的值。
通常情况下,您的匹配器会将 Probe.probe
中的 return 值与实际值进行比较。