aboutsummaryrefslogtreecommitdiffhomepage
path: root/ruby
diff options
context:
space:
mode:
authorGravatar Chris Fallin <cfallin@c1f.net>2015-05-02 19:02:08 -0700
committerGravatar Chris Fallin <cfallin@c1f.net>2015-05-02 19:02:08 -0700
commit16a283f7942be34eb47852832131dfef2d196f83 (patch)
treed99562c8fc9052afd1aced0aa9709a25637bdc7c /ruby
parentdcf12136835af5239f0877aa455eabbd7b88b61e (diff)
parent64678265c5ae28998d031900c2de52419a8ed7e4 (diff)
Merge pull request #334 from skippy/allow-msg-to-accept-nil
ruby: allow a message field to be unset
Diffstat (limited to 'ruby')
-rw-r--r--ruby/ext/google/protobuf_c/storage.c4
-rw-r--r--ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java15
-rw-r--r--ruby/tests/basic.rb2
3 files changed, 15 insertions, 6 deletions
diff --git a/ruby/ext/google/protobuf_c/storage.c b/ruby/ext/google/protobuf_c/storage.c
index 5b1549d2..2ad8bd74 100644
--- a/ruby/ext/google/protobuf_c/storage.c
+++ b/ruby/ext/google/protobuf_c/storage.c
@@ -155,7 +155,9 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
break;
}
case UPB_TYPE_MESSAGE: {
- if (CLASS_OF(value) != type_class) {
+ if (CLASS_OF(value) == CLASS_OF(Qnil)) {
+ value = Qnil;
+ } else if (CLASS_OF(value) != type_class) {
rb_raise(rb_eTypeError,
"Invalid type %s to assign to submessage field.",
rb_class2name(CLASS_OF(value)));
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
index 20e825e2..c7fd7aa7 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
@@ -659,14 +659,14 @@ public class RubyMessage extends RubyObject {
} else {
Descriptors.FieldDescriptor.Type fieldType = fieldDescriptor.getType();
IRubyObject typeClass = context.runtime.getObject();
+ boolean addValue = true;
if (fieldType == Descriptors.FieldDescriptor.Type.MESSAGE) {
typeClass = ((RubyDescriptor) getDescriptorForField(context, fieldDescriptor)).msgclass(context);
+ if (value.isNil()){
+ addValue = false;
+ }
} else if (fieldType == Descriptors.FieldDescriptor.Type.ENUM) {
typeClass = ((RubyEnumDescriptor) getDescriptorForField(context, fieldDescriptor)).enummodule(context);
- }
- Utils.checkType(context, fieldType, value, (RubyModule) typeClass);
- // Convert integer enum to symbol
- if (fieldType == Descriptors.FieldDescriptor.Type.ENUM) {
Descriptors.EnumDescriptor enumDescriptor = fieldDescriptor.getEnumType();
if (Utils.isRubyNum(value)) {
Descriptors.EnumValueDescriptor val =
@@ -674,7 +674,12 @@ public class RubyMessage extends RubyObject {
if (val.getIndex() != -1) value = context.runtime.newSymbol(val.getName());
}
}
- this.fields.put(fieldDescriptor, value);
+ if (addValue) {
+ Utils.checkType(context, fieldType, value, (RubyModule) typeClass);
+ this.fields.put(fieldDescriptor, value);
+ } else {
+ this.fields.remove(fieldDescriptor);
+ }
}
}
return context.runtime.getNil();
diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb
index 141ce7c5..1c2a03dc 100644
--- a/ruby/tests/basic.rb
+++ b/ruby/tests/basic.rb
@@ -154,6 +154,8 @@ module BasicTest
assert m.optional_bytes == "world"
m.optional_msg = TestMessage2.new(:foo => 42)
assert m.optional_msg == TestMessage2.new(:foo => 42)
+ m.optional_msg = nil
+ assert m.optional_msg == nil
end
def test_ctor_args