我遇到了这段代码:
class RandomSequence
def initialize(limit,num)
@limit,@num = limit,num
end
def each
@num.times { yield (rand * @limit).floor }
end
end
i = -1
RandomSequence.new(10,4).each do |num|
i = num if i < num
end
是否只调用each
方法一次并计算四个不同的值,然后对于每个值,我们在do
和end
之间执行代码块?我对控制流程的理解是否正确?
答案 0 :(得分:2)
你的理解很接近。将生成随机数,然后生成块,然后生成另一个等4次。您可以通过将puts
语句添加到块中来轻松验证这一点,以查看它们何时执行。
class RandomSequence
def initialize(limit,num)
@limit,@num = limit,num
end
def each
puts "in each"
@num.times { yield (rand.tap {|x| puts "Generated #{x}" } * @limit).floor }
end
end
i = -1
RandomSequence.new(10,4).each do |num|
puts "in block"
i = num if i < num
end
输出
in each
Generated 0.6724385316643955
in block
Generated 0.8906983274750662
in block
Generated 0.49038868732214036
in block
Generated 0.38100454011243456
in block
答案 1 :(得分:1)
each
类上的RandomSequence
方法被调用一次。其中@num.times
创建Enumerator
。迭代Enumerator
并调用带有yield
语句的块(忽略它的参数)。
yield
语句调用传递给each
方法的块传递(rand * @limit).floor
的值。在您的代码中,块不绑定到变量,即您可以通过执行以下操作来获取对块的引用:
def each(&block)
#... do stuff with block, e.g. block.call("some args")
end
这有时很有用。
有点偏离主题,但有一件事我发现Ruby开始时很可怕的是return
语句返回从定义它的位置执行的流程。
def create_proc
puts "Creating proc"
Proc.new do
puts "In proc!"
return "some value" # notice the explicit return
end
end
def do_stuff
my_proc = create_proc
my_proc.call # This will cause a runtime error
end
如果显式return
被删除,那么一切正常就没有错误......教训是,在ruby中你应该避免使用显式返回。