Home > OS >  Array member becomes the same after push in my Ruby code
Array member becomes the same after push in my Ruby code

Time:05-17

In my Ruby code, a long hex string is parsed and pushed into a data array (avl_data_array.push(avl_data)). After pushing, when I use puts to display the array, all the elements are the same...

The code is:

data_hex_string = '03D8CAFE01D0000F383630323634303535353134323532081100000180BB016382005B29ED2AEF935C0D00000000000000000C0616004701F0001502C800EF000643273A440000B50012B60010422F2B180000000000000180BACA745E005B29ED2AEF935C0D003000000B0000000C0616004703F0001503C800EF00064326A2440000B5000CB60008422F41180000000000000180BA938536005B29ED2AEF935C0D00270000090000000C0616004703F0001503C800EF0006432705440000B5000CB60008422F19180000000000000180BA5C960E005B29ED2AEF935C0D003200000B0000000C0616004703F0001504C800EF00064328A4440033B5000BB60008422EEC180000000000000180BA1F8371005B29ED2AEF935C0D000000000000000008041600F000C801EF00044326B7440000422F73180000000000000180B9E89182005B29ED2AEF935C0D000000000000000008041600F000C801EF000443268B440000422F30180000000000000180B9B19F93005B29ED2AEF935C0D000000000000000008041600F000C801EF0004432690440000422EED180000000000000180B97AB11B005B29ED2AEF935C0D00000000000000000C0616004703F0001503C801EF0006432672440000B50000B60000422F31180000000000000180B943C385005B29ED2AEF935C0D00000000000000000C0616004703F0001503C801EF0006432681440000B50000B60000422EDA180000000000000180B90CD40F005B29ED2AEF935C0D00000000000000000C0616004703F0001504C801EF0006432681440000B50000B60000422F26180000000000000180B8D5E778005B29ED2AEF935C0D00000000000000000C0616004703F0001504C801EF0006432677440000B50000B60000422F30180000000000000180B89EF589005B29ED2AEF935C0D000000000000000008041600F000C801EF0004432681440000422F30180000000000000180B868034C005B29ED2AEF935C0D00000000000000000C0616004703F0001503C801EF000643267C440000B50000B60000422F0A180000000000000180B83111AB005B29ED2AEF935C0D000000000000000008041600F000C801EF000443267C440000422F3A180000000000000180B7FA1ECA005B29ED2AEF935C0D00000000000000000C0616004704F0001503C801EF0006432681440000B50000B60000422F1D180000000000000180B7C332F5005B29ED2AEF935C0D00000000000000000C0616004704F0001504C801EF0006432686440000B50000B60000422F30180000000000000180B78C431E005B29ED2AEF935C0D000000000000000008041600F000C801EF0004432686440000422F8F180000000011'

avl_data_header = {}
avl_data = {}
avl_data_array = [] 
avl_data_footer = {}

avl_data_header[:packet_len] = data_hex_string[0..3]
avl_data_header[:packet_id] = data_hex_string[4..7]
avl_data_header[:not_usable_byte] = data_hex_string[8..9]
avl_data_header[:avl_packet_id] = data_hex_string[10..11]
avl_data_header[:imei_len] = data_hex_string[12..15]

imei_len_dec = data_hex_string[12..15].to_i(16)
current_add = 16
offset = imei_len_dec * 2
avl_data_header[:imei] = data_hex_string[current_add..(current_add offset-1)]

current_add = current_add offset
offset = 2
avl_data_header[:codec_id] = data_hex_string[current_add..(current_add offset-1)]

current_add = current_add offset
offset = 2
avl_data_header[:number_data1] = data_hex_string[current_add..(current_add offset-1)]

data_num = avl_data_header[:number_data1].to_i(16)

for a in 0..(data_num-1) do
  current_add = current_add offset
  offset = 2 * 8
  avl_data[:timestamp] = data_hex_string[current_add..(current_add offset-1)]

  current_add = current_add offset
  offset = 2
  avl_data[:priority] = data_hex_string[current_add..(current_add offset-1)]

  current_add = current_add offset
  offset = 2 * 4
  avl_data[:longitude] = data_hex_string[current_add..(current_add offset-1)]

  current_add = current_add offset
  offset = 2 * 4
  avl_data[:latitude] = data_hex_string[current_add..(current_add offset-1)]

  current_add = current_add offset
  offset = 2 * 2
  avl_data[:altitude] = data_hex_string[current_add..(current_add offset-1)]

  current_add = current_add offset
  offset = 2 * 2
  avl_data[:angle] = data_hex_string[current_add..(current_add offset-1)]

  current_add = current_add offset
  offset = 2
  avl_data[:satellites] = data_hex_string[current_add..(current_add offset-1)]

  current_add = current_add offset
  offset = 2 * 2
  avl_data[:speed] = data_hex_string[current_add..(current_add offset-1)]
  
  avl_data_array.push(avl_data)
end

current_add = current_add offset
offset = 2
avl_data_footer[:number_data2] = data_hex_string[current_add..(current_add offset-1)]

current_add = current_add offset
offset = 2 * 4
avl_data_footer[:crc_16] = data_hex_string[current_add..(current_add offset-1)]
    
puts "header: #{avl_data_header}"
puts "data:"
puts avl_data_array
puts "footer: #{avl_data_footer}"

The result is:

header: {:packet_len=>"03D8", :packet_id=>"CAFE", :not_usable_byte=>"01", :avl_packet_id=>"D0", :imei_len=>"000F", :imei=>"383630323634303535353134323532", :codec_id=>"08", :number_data1=>"11"}
data:
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
{:timestamp=>"ED18000000000000", :priority=>"01", :longitude=>"80B97AB1", :latitude=>"1B005B29", :altitude=>"ED2A", :angle=>"EF93", :satellites=>"5C", :speed=>"0D00"}
footer: {:number_data2=>"00", :crc_16=>"00000000"}

The element in array data should be different. I am Ruby newbie, but it seems the grammer in my code is correct. Why this happens?

CodePudding user response:

Why this happens?

You never change avl_data. It is always the same object. Hence, you push the same object to the Array in avl_data_array over and over again.

Here is a reduced version of your code demonstrating the problem more clearly:

single_array_element = {}
array = []

3.times do |i|
  single_array_element[:i] = i
  array << single_array_element
end

array.all? {|el| single_array_element.object_id == el.object_id}
#=> true

array
#=> [{ i: 2 }, { i: 2 }, { i: 2 }]

I am Ruby newbie, but it seems the grammer in my code is correct.

The syntax is indeed correct, otherwise the program would not even run – the parser would abort with a SyntaxError. But the semantics aren't: The code you wrote is 100% valid Ruby code, it is not an error.

Ruby is doing exactly what you are telling her to do, you just told it to do the wrong thing.

  •  Tags:  
  • ruby
  • Related