Skip to content

Struct#to_a returns an array that is linked to the struct #5372

@larskanis

Description

@larskanis

Environment

Provide at least:

  • JRuby version (jruby -v) and command line (flags, JRUBY_OPTS, etc)
    • jruby 9.2.0.0 (2.5.0) 2018-05-24 81156a8 OpenJDK 64-Bit Server VM 10.0.2+13-Ubuntu-1ubuntu0.18.04.2 on 10.0.2+13-Ubuntu-1ubuntu0.18.04.2 +jit [linux-x86_64]
  • Operating system and platform (e.g. uname -a)
    • Linux netzbuch 4.15.0-36-generic #39-Ubuntu SMP Mon Sep 24 16:19:09 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

Expected Behavior

Struct#to_a and Struct#values should return an Array which is independent to the Struct. So subsequent modifications to the struct should not be visible in a previously retrieved values array. In MRI a new Array is created at each call to #values or #to_a.

S = Struct.new :a, :b, :c
s = S.new 1, 2, 3
vs = s.values
p vs    # => [1, 2, 3]
s.b = 7
p vs    # => [1, 2, 3]

Actual Behavior

However in JRuby modifications to the struct are passed through to the retrieved array, when the struct has more than two members:

S = Struct.new :a, :b, :c
s = S.new 1, 2, 3
vs = s.values
p vs    # => [1, 2, 3]
s.b = 7
p vs    # => [1, 7, 3]

This is still the case, when using Array#dup:

S = Struct.new :a, :b, :c
s = S.new 1, 2, 3
vs = s.to_a.dup
p vs    # => [1, 2, 3]
s.b = 7
p vs    # => [1, 7, 3]

But correct behavior when using Array.map:

S = Struct.new :a, :b, :c
s = S.new 1, 2, 3
vs = s.to_a.map{|a| a }
p vs    # => [1, 2, 3]
s.b = 7
p vs    # => [1, 2, 3]

Correct behavior also in JRuby when there are less than three members:

S = Struct.new :a, :b
s = S.new 1, 2
vs = s.values
p vs    # => [1, 2]
s.b = 7
p vs    # => [1, 2]

This is probably something that should be verified through ruby-spec, isn't it?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions