简体   繁体   中英

Ruby odd behavior of Array.each


class Point
  attr_accessor :x, :y
  
  def initialize(x =0, y = 0)
    @x = x
    @y = y
  end
  
  def to_s
    "x: #{@x}; y: #{@y}"
  end
  
  def move(x,y)
    @x =  @x + x
    @y =  @y + y
  end
end


my_point= Point.new(4,6)
puts my_point
my_point.move(7,14)
puts my_point
puts

my_square = Array.new(4, Point.new)
a_square = []
my_square.each {|i| puts i}
puts

my_square.each do|i| 
   b = i
  b.move(2,4)
  a_square<< b
end

a_square.each {|i| puts i}
The result

x: 4; y: 6
x: 11; y: 20

x: 0; y: 0
x: 0; y: 0
x: 0; y: 0
x: 0; y: 0

x: 8; y: 16
x: 8; y: 16
x: 8; y: 16
x: 8; y: 16

when it should be

x: 4; y: 6
x: 11; y: 20

x: 0; y: 0
x: 0; y: 0
x: 0; y: 0
x: 0; y: 0

x:2; y: 4
x:2; y: 4
x:2; y: 4
x:2; y: 4

Array.new(4, Point.new) will create an array with the same object (in this case an instance of Point).

my_square = Array.new(4, Point.new)
p my_square.map(&:object_id).uniq.count
#=> 1

If you change to Array.new(4) { Point.new } , this will populate array with different objects.

my_square = Array.new(4) { Point.new }
p my_square.map(&:object_id).uniq.count
#=> 4

Check this for more info.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM