|  | @@ -316,6 +316,29 @@ VALUE RepeatedField_deep_copy(VALUE _self) {
 | 
	
		
			
				|  |  |    return new_rptfield;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * call-seq:
 | 
	
		
			
				|  |  | + *     RepeatedField.to_ary => array
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Used when converted implicitly into array, e.g. compared to an Array.
 | 
	
		
			
				|  |  | + * Also called as a fallback of Object#to_a
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +VALUE RepeatedField_to_ary(VALUE _self) {
 | 
	
		
			
				|  |  | +  RepeatedField* self = ruby_to_RepeatedField(_self);
 | 
	
		
			
				|  |  | +  upb_fieldtype_t field_type = self->field_type;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  size_t elem_size = native_slot_size(field_type);
 | 
	
		
			
				|  |  | +  size_t off = 0;
 | 
	
		
			
				|  |  | +  VALUE ary = rb_ary_new2(self->size);
 | 
	
		
			
				|  |  | +  for (int i = 0; i < self->size; i++, off += elem_size) {
 | 
	
		
			
				|  |  | +    void* mem = ((uint8_t *)self->elements) + off;
 | 
	
		
			
				|  |  | +    VALUE elem = native_slot_get(field_type, self->field_type_class, mem);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    rb_ary_push(ary, elem);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  return ary;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /*
 | 
	
		
			
				|  |  |   * call-seq:
 | 
	
		
			
				|  |  |   *     RepeatedField.==(other) => boolean
 | 
	
	
		
			
				|  | @@ -335,15 +358,9 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    RepeatedField* self = ruby_to_RepeatedField(_self);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  // Inefficient but workable: to support comparison to a generic array, we
 | 
	
		
			
				|  |  | -  // build a temporary RepeatedField of our type.
 | 
	
		
			
				|  |  |    if (TYPE(_other) == T_ARRAY) {
 | 
	
		
			
				|  |  | -    VALUE new_rptfield = RepeatedField_new_this_type(_self);
 | 
	
		
			
				|  |  | -    for (int i = 0; i < RARRAY_LEN(_other); i++) {
 | 
	
		
			
				|  |  | -      VALUE elem = rb_ary_entry(_other, i);
 | 
	
		
			
				|  |  | -      RepeatedField_push(new_rptfield, elem);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    _other = new_rptfield;
 | 
	
		
			
				|  |  | +    VALUE self_ary = RepeatedField_to_ary(_self);
 | 
	
		
			
				|  |  | +    return rb_equal(self_ary, _other);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    RepeatedField* other = ruby_to_RepeatedField(_other);
 | 
	
	
		
			
				|  | @@ -401,29 +418,8 @@ VALUE RepeatedField_hash(VALUE _self) {
 | 
	
		
			
				|  |  |   * representation computed by its own #inspect method.
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  VALUE RepeatedField_inspect(VALUE _self) {
 | 
	
		
			
				|  |  | -  RepeatedField* self = ruby_to_RepeatedField(_self);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  VALUE str = rb_str_new2("[");
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  bool first = true;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  upb_fieldtype_t field_type = self->field_type;
 | 
	
		
			
				|  |  | -  VALUE field_type_class = self->field_type_class;
 | 
	
		
			
				|  |  | -  size_t elem_size = native_slot_size(field_type);
 | 
	
		
			
				|  |  | -  size_t off = 0;
 | 
	
		
			
				|  |  | -  for (int i = 0; i < self->size; i++, off += elem_size) {
 | 
	
		
			
				|  |  | -    void* mem = ((uint8_t *)self->elements) + off;
 | 
	
		
			
				|  |  | -    VALUE elem = native_slot_get(field_type, field_type_class, mem);
 | 
	
		
			
				|  |  | -    if (!first) {
 | 
	
		
			
				|  |  | -      str = rb_str_cat2(str, ", ");
 | 
	
		
			
				|  |  | -    } else {
 | 
	
		
			
				|  |  | -      first = false;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    str = rb_str_append(str, rb_funcall(elem, rb_intern("inspect"), 0));
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  str = rb_str_cat2(str, "]");
 | 
	
		
			
				|  |  | -  return str;
 | 
	
		
			
				|  |  | +  VALUE self_ary = RepeatedField_to_ary(_self);
 | 
	
		
			
				|  |  | +  return rb_funcall(self_ary, rb_intern("inspect"), 0);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /*
 | 
	
	
		
			
				|  | @@ -594,6 +590,7 @@ void RepeatedField_register(VALUE module) {
 | 
	
		
			
				|  |  |    // Also define #clone so that we don't inherit Object#clone.
 | 
	
		
			
				|  |  |    rb_define_method(klass, "clone", RepeatedField_dup, 0);
 | 
	
		
			
				|  |  |    rb_define_method(klass, "==", RepeatedField_eq, 1);
 | 
	
		
			
				|  |  | +  rb_define_method(klass, "to_ary", RepeatedField_to_ary, 0);
 | 
	
		
			
				|  |  |    rb_define_method(klass, "hash", RepeatedField_hash, 0);
 | 
	
		
			
				|  |  |    rb_define_method(klass, "inspect", RepeatedField_inspect, 0);
 | 
	
		
			
				|  |  |    rb_define_method(klass, "+", RepeatedField_plus, 1);
 |