Переглянути джерело

When initializing a message, skip a field if value is nil (#3693)

Zachary Anker 7 роки тому
батько
коміт
70544627cb

+ 4 - 0
ruby/ext/google/protobuf_c/message.c

@@ -256,6 +256,10 @@ int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
              "Unknown field name '%s' in initialization map entry.", name);
   }
 
+  if (TYPE(val) == T_NIL) {
+    return 0;
+  }
+
   if (is_map_field(f)) {
     VALUE map;
 

+ 2 - 0
ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java

@@ -86,6 +86,8 @@ public class RubyMessage extends RubyObject {
                         throw runtime.newTypeError("Expected string or symbols as hash keys in initialization map.");
                     final Descriptors.FieldDescriptor fieldDescriptor = findField(context, key);
 
+                    if (value.isNil()) return;
+
                     if (Utils.isMapEntry(fieldDescriptor)) {
                         if (!(value instanceof RubyHash))
                             throw runtime.newArgumentError("Expected Hash object as initializer value for map field '" +  key.asJavaString() + "'.");

+ 9 - 0
ruby/tests/basic.rb

@@ -212,6 +212,15 @@ module BasicTest
       assert_equal ['foo', 'bar'], m.repeated_string
     end
 
+    def test_ctor_nil_args
+      m = TestMessage.new(:optional_enum => nil, :optional_int32 => nil, :optional_string => nil, :optional_msg => nil)
+
+      assert_equal :Default, m.optional_enum
+      assert_equal 0, m.optional_int32
+      assert_equal "", m.optional_string
+      assert_nil m.optional_msg
+    end
+
     def test_embeddedmsg_hash_init
       m = TestEmbeddedMessageParent.new(:child_msg => {sub_child: {optional_int32: 1}},
                                         :number => 2,