Ruby中Ractor.select方法的move布尔标志作用是什么?
Ruby Ractor.select中move标志的行为解析
我正尝试理解Ruby中Ractor.select方法里move标志的行为,文档对该标志的描述为:
move boolean flag defines whether yielded value should be copied (default) or moved.
这在Rust这类有所有权模型的语言中容易理解,但我想知道在Ruby中这意味着什么。
实验1:数组类型测试
我先运行了一段代码测试move标志的效果:
should_move = true puts "MOVE: #{should_move}" r1 = Ractor.new do data = [{name: "tom"}, {name: "dick"}, {name: "harry"}] puts "[INSIDE RACTOR] data value is #{data} and data object id is :#{data[0].object_id}" Ractor.yield(data) sleep 2 puts "[INSIDE RACTOR] data value is #{data} and data object id is :#{data[0].object_id}" end ractor, value = Ractor.select(r1, move: should_move) puts "[OUTSIDE RACTOR] value is: #{value} and value[0] object_id is: #{value[0].object_id}" p ractor sleep 3
将should_move设为true和false时,输出结果一致:
MOVE: true main.rb:4: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. [INSIDE RACTOR (before move)] data value is [{:name=>"tom"}, {:name=>"dick"}, {:name=>"harry"}] and data object id is :60 [OUTSIDE RACTOR (after move)] value is: [{:name=>"tom"}, {:name=>"dick"}, {:name=>"harry"}] and value[0] object_id is: 80 #<Ractor:#2 main.rb:4 blocking> [INSIDE RACTOR (after move)] data value is [{:name=>"tom"}, {:name=>"dick"}, {:name=>"harry"}] and data object id is :60
实验2:整数类型测试
之后我将Ractor内的data变量改为整数值:
should_move = true puts "MOVE: #{should_move}" r1 = Ractor.new do data = 12 puts "[INSIDE RACTOR] data value is #{data} and data object id is :#{data.object_id}" Ractor.yield(data) sleep 2 puts "[INSIDE RACTOR] data value is #{data} and data object id is :#{data.object_id}" end ractor, value = Ractor.select(r1, move: should_move) puts "[OUTSIDE RACTOR] value is: #{value} and value object_id is: #{value.object_id}" p ractor sleep 3
此次实验中move标志的状态同样未影响输出:
MOVE: false main.rb:4: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. [INSIDE RACTOR (before move)] data value is 12 and data object id is :25 [OUTSIDE RACTOR (after move)] value is: 12 and value object_id is: 25 #<Ractor:#2 main.rb:4 blocking> [INSIDE RACTOR (after move)] data value is 12 and data object id is :25
为什么实验中move标志没体现差异?
- 不可变对象的特殊性:Ruby中的小整数属于不可变的共享对象,无论是否开启move,它们的object_id都不会改变,原Ractor也能正常访问——因为不可变对象不存在并发修改风险,Ruby会直接共享而非复制或移动。
- 可变对象的访问限制未触发:在数组实验中,虽然
move: true时对象所有权已转移到外部Ractor,但原Ractor只是读取对象值而非修改,所以没有触发错误。如果在Ractor.yield(data)后尝试修改data(比如data[0][:name] = "jerry"),当move: true时会直接抛出Ractor::MovedError,而move: false(默认复制)时则可以正常修改,因为原Ractor持有的是独立副本。
内容的提问来源于stack exchange,提问作者sreedev
相关产品推荐
相关产品推荐

