Ruby:光纤产量和带有参数的fiber.resume -

时间:2017-02-02 09:29:36

标签: ruby

我正在学习红宝石......我是编程新手

fiber = Fiber.new do |first|
  second = Fiber.yield first + 2
end

puts fiber.resume 10
puts fiber.resume 14
puts fiber.resume 18

12
14
FiberError: dead fiber called

我认为,首先是fiber.resume调用在第一个Fiber.yield之前执行所有语句,当执行Fiber.yield时,它会在第一个fibre.resume之后将控制转移到该行,并且值(first + 2)变为返回值第一个光纤。所以把光纤.sresume打印12,所以下一行也是fiber.resume。现在,First Fiber.yield转移控制,因此当您调用第二个fiber.resume时,应该执行Fiber.yield之后的下一行。但是在第一次Fiber.yield之后没有声明,那么我怎么得到14.我读到我们可以得到最后一个声明,但它没有得到来自fiber.resume的输入,它甚至没有。

并且没有阻止局部变量

irb(main):007:0> fiber = Fiber.new do |first|
irb(main):008:1* Fiber.yield first + 2
irb(main):009:1> end
=> #<Fiber:0x23fb4a0>
irb(main):010:0>
irb(main):011:0* puts fiber.resume 10
12
=> nil
irb(main):012:0> puts fiber.resume 10
10
=> nil
irb(main):013:0> puts fiber.resume 10
FiberError: dead fiber called
        from (irb):13:in `resume'
        from (irb):13
        from C:/Ruby23/bin/irb.cmd:19:in `<main>'
irb(main):014:0>

请帮助我了解它是如何运作的。

1 个答案:

答案 0 :(得分:3)

  

第一个fiber.resume调用会在第一个Fiber.yield之前执行所有语句,执行Fiber.yield时会将控制转移到第一个fiber.resume之后的行和值first+2 })成为第一个fiber.resume的返回值,因此puts fiber.resume打印12

这几乎是正确的。该块实际上已在此处停止:

fiber = Fiber.new do |first|
  second = ...

光纤悬挂在该任务的中间。无法完成赋值,因为Fiber.yield将控制权交还给调用上下文,并传递12

然后,呼叫fiber.resume 14将恢复光纤,并且可以完成分配:

fiber = Fiber.new do |first|
  second = 14

14是第二份简历传递的值。

该块现在可以完成,fiber.resume返回。但这一次,返回值由块的返回值(14确定,因为second = 14计算为14)。

也许这种方式变得更加明显:

fiber = Fiber.new do |first|
  second = Fiber.yield first + 2
  third = Fiber.yield second + 3
  third + 4
end

puts fiber.resume 10
# prints 12 (10 + 2)
puts fiber.resume 14
# prints 17 (14 + 3)
puts fiber.resume 16
# prints 20 (16 + 4)
puts fiber.resume 18
# dead fiber called (FiberError)