Skip to content

Commit

Permalink
[fix] set regression with YAML.load
Browse files Browse the repository at this point in the history
YAML doesn't have proper treatment for Set serialization, it dumps it
just like any Ruby object, meaning on YAML.load will allocate an simply
"initialize" all i-vars (Set's internal @hash - due MRI compatibility)

resolves GH-5222
kares committed Jun 18, 2018
1 parent f87acc5 commit 5a244b8
Showing 3 changed files with 26 additions and 2 deletions.
12 changes: 12 additions & 0 deletions core/src/main/java/org/jruby/ext/set/RubySet.java
Original file line number Diff line number Diff line change
@@ -239,6 +239,18 @@ private static IRubyObject doWithEnum(final ThreadContext context, final IRubyOb
throw context.runtime.newArgumentError("value must be enumerable");
}

// YAML doesn't have proper treatment for Set serialization, it dumps it just like
// any Ruby object, meaning on YAML.load will allocate an "initialize" all i-vars!
@Override
public IRubyObject instance_variable_set(IRubyObject name, IRubyObject value) {
if (getRuntime().newSymbol("@hash").equals(name)) {
if (value instanceof RubyHash) {
setHash((RubyHash) value); return value;
}
}
return super.instance_variable_set(name, value);
}

IRubyObject invokeAdd(final ThreadContext context, final IRubyObject val) {
return this.callMethod(context,"add", val); // TODO site-cache
}
1 change: 1 addition & 0 deletions test/jruby.index
Original file line number Diff line number Diff line change
@@ -65,6 +65,7 @@ jruby/test_random
jruby/test_rbconfig
jruby/test_require_once
jruby/test_respond_to
jruby/test_set
jruby/test_socket
jruby/test_string_java_bytes
jruby/test_string_printf
15 changes: 13 additions & 2 deletions test/jruby/test_set.rb
Original file line number Diff line number Diff line change
@@ -63,6 +63,17 @@ def test_marshal_dump
assert_equal Set.new([1, 2]), set
end

def test_yaml_dump; require 'yaml'
str = YAML.dump(Set.new)
assert_equal "--- !ruby/object:Set\nhash: {}\n", str
set = YAML.load(str)
assert_equal Set.new([]), set

str = YAML.dump(SortedSet.new([2, 3, 1]))
set = YAML.load(str)
assert_equal SortedSet.new([1, 2, 3]), set
end

def test_sorted_marshal_dump
dump = Marshal.dump(SortedSet.new)
assert_equal SortedSet.new, Marshal.load(dump)
@@ -116,13 +127,13 @@ def test_dup_to_a

def test_to_java
assert set = Set.new.to_java
assert set.toString.start_with?('#<Set:0x')
assert_equal "#<Set: {}>", set.toString
assert_equal org.jruby.ext.set.RubySet, set.class
assert set.is_a?(java.util.Set)
assert_equal java.util.HashSet.new, set

assert set = SortedSet.new([2, 1]).to_java
assert set.toString.start_with?('#<SortedSet:0x')
assert set.toString.start_with?('#<SortedSet: {')
assert_equal org.jruby.ext.set.RubySortedSet, set.class
assert set.is_a?(java.util.Set)
assert set.is_a?(java.util.SortedSet)

0 comments on commit 5a244b8

Please sign in to comment.