This is an automated email from the ASF dual-hosted git repository.

kou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new 15151972ff GH-48410: [Ruby] Add support for reading large list array 
(#48411)
15151972ff is described below

commit 15151972ffaf7906e08c2d93d11547b8d7370b90
Author: Sutou Kouhei <[email protected]>
AuthorDate: Wed Dec 10 06:27:33 2025 +0900

    GH-48410: [Ruby] Add support for reading large list array (#48411)
    
    ### Rationale for this change
    
    It's a large variant of list array.
    
    ### What changes are included in this PR?
    
    * Add `ArrowFormat::LargeListType`
    * Add `ArrowFormat::LargeListArray`
    * Improve large list support in Red Arrow
    
    ### Are these changes tested?
    
    Yes.
    
    ### Are there any user-facing changes?
    
    Yes.
    * GitHub Issue: #48410
    
    Authored-by: Sutou Kouhei <[email protected]>
    Signed-off-by: Sutou Kouhei <[email protected]>
---
 ruby/red-arrow-format/lib/arrow-format/array.rb    |  18 +++-
 .../lib/arrow-format/file-reader.rb                |   3 +
 ruby/red-arrow-format/lib/arrow-format/type.rb     |  10 ++
 ruby/red-arrow-format/test/test-file-reader.rb     |  12 +++
 ruby/red-arrow/ext/arrow/converters.cpp            |   5 +
 ruby/red-arrow/ext/arrow/converters.hpp            | 115 +++++++++++++++++++++
 ruby/red-arrow/ext/arrow/values.cpp                |   1 +
 .../lib/arrow/large-list-array-builder.rb          |  29 ++++++
 ruby/red-arrow/lib/arrow/large-list-data-type.rb   |  83 +++++++++++++++
 ruby/red-arrow/lib/arrow/libraries.rb              |   4 +
 ruby/red-arrow/lib/arrow/list-array-builder.rb     |  70 +------------
 ruby/red-arrow/lib/arrow/list-data-type.rb         |  36 +------
 ruby/red-arrow/lib/arrow/list-field-resolvable.rb  |  50 +++++++++
 ...-array-builder.rb => list-values-appendable.rb} |  15 +--
 14 files changed, 336 insertions(+), 115 deletions(-)

diff --git a/ruby/red-arrow-format/lib/arrow-format/array.rb 
b/ruby/red-arrow-format/lib/arrow-format/array.rb
index ea728ce8ce..251ef8c846 100644
--- a/ruby/red-arrow-format/lib/arrow-format/array.rb
+++ b/ruby/red-arrow-format/lib/arrow-format/array.rb
@@ -172,7 +172,7 @@ module ArrowFormat
     def to_a
       child_values = @child.to_a
       values = @offsets_buffer.
-        each(:s32, 0, @size + 1). # TODO: big endian support
+        each(offset_type, 0, @size + 1).
         each_cons(2).
         collect do |(_, offset), (_, next_offset)|
         child_values[offset...next_offset]
@@ -182,6 +182,17 @@ module ArrowFormat
   end
 
   class ListArray < VariableSizeListArray
+    private
+    def offset_type
+      :s32 # TODO: big endian support
+    end
+  end
+
+  class LargeListArray < VariableSizeListArray
+    private
+    def offset_type
+      :s64 # TODO: big endian support
+    end
   end
 
   class StructArray < Array
@@ -215,5 +226,10 @@ module ArrowFormat
         end
       end
     end
+
+    private
+    def offset_type
+      :s32 # TODO: big endian support
+    end
   end
 end
diff --git a/ruby/red-arrow-format/lib/arrow-format/file-reader.rb 
b/ruby/red-arrow-format/lib/arrow-format/file-reader.rb
index 3b2dc22823..0e80d1c119 100644
--- a/ruby/red-arrow-format/lib/arrow-format/file-reader.rb
+++ b/ruby/red-arrow-format/lib/arrow-format/file-reader.rb
@@ -28,6 +28,7 @@ require_relative "org/apache/arrow/flatbuf/floating_point"
 require_relative "org/apache/arrow/flatbuf/footer"
 require_relative "org/apache/arrow/flatbuf/int"
 require_relative "org/apache/arrow/flatbuf/large_binary"
+require_relative "org/apache/arrow/flatbuf/large_list"
 require_relative "org/apache/arrow/flatbuf/list"
 require_relative "org/apache/arrow/flatbuf/map"
 require_relative "org/apache/arrow/flatbuf/message"
@@ -161,6 +162,8 @@ module ArrowFormat
         end
       when Org::Apache::Arrow::Flatbuf::List
         type = ListType.new(read_field(fb_field.children[0]))
+      when Org::Apache::Arrow::Flatbuf::LargeList
+        type = LargeListType.new(read_field(fb_field.children[0]))
       when Org::Apache::Arrow::Flatbuf::Struct
         children = fb_field.children.collect {|child| read_field(child)}
         type = StructType.new(children)
diff --git a/ruby/red-arrow-format/lib/arrow-format/type.rb 
b/ruby/red-arrow-format/lib/arrow-format/type.rb
index 7726c23325..f544f6bea8 100644
--- a/ruby/red-arrow-format/lib/arrow-format/type.rb
+++ b/ruby/red-arrow-format/lib/arrow-format/type.rb
@@ -214,6 +214,16 @@ module ArrowFormat
     end
   end
 
+  class LargeListType < VariableSizeListType
+    def initialize(child)
+      super("LargeList", child)
+    end
+
+    def build_array(size, validity_buffer, offsets_buffer, child)
+      LargeListArray.new(self, size, validity_buffer, offsets_buffer, child)
+    end
+  end
+
   class StructType < Type
     attr_reader :children
     def initialize(children)
diff --git a/ruby/red-arrow-format/test/test-file-reader.rb 
b/ruby/red-arrow-format/test/test-file-reader.rb
index 9748ede47d..d9df86af05 100644
--- a/ruby/red-arrow-format/test/test-file-reader.rb
+++ b/ruby/red-arrow-format/test/test-file-reader.rb
@@ -140,6 +140,18 @@ class TestFileReader < Test::Unit::TestCase
     end
   end
 
+  sub_test_case("LargeList") do
+    def build_array
+      data_type = Arrow::LargeListDataType.new(name: "count", type: :int8)
+      Arrow::LargeListArray.new(data_type, [[-128, 127], nil, [-1, 0, 1]])
+    end
+
+    def test_read
+      assert_equal([{"value" => [[-128, 127], nil, [-1, 0, 1]]}],
+                   read)
+    end
+  end
+
   sub_test_case("Struct") do
     def build_array
       data_type = Arrow::StructDataType.new(count: :int8,
diff --git a/ruby/red-arrow/ext/arrow/converters.cpp 
b/ruby/red-arrow/ext/arrow/converters.cpp
index f3bfa6f34a..bbabe60b7d 100644
--- a/ruby/red-arrow/ext/arrow/converters.cpp
+++ b/ruby/red-arrow/ext/arrow/converters.cpp
@@ -25,6 +25,11 @@ namespace red_arrow {
     return list_array_value_converter_->convert(array, i);
   }
 
+  VALUE ArrayValueConverter::convert(const arrow::LargeListArray& array,
+                                     const int64_t i) {
+    return large_list_array_value_converter_->convert(array, i);
+  }
+
   VALUE ArrayValueConverter::convert(const arrow::StructArray& array,
                                      const int64_t i) {
     return struct_array_value_converter_->convert(array, i);
diff --git a/ruby/red-arrow/ext/arrow/converters.hpp 
b/ruby/red-arrow/ext/arrow/converters.hpp
index 6406925ca0..1689a6805b 100644
--- a/ruby/red-arrow/ext/arrow/converters.hpp
+++ b/ruby/red-arrow/ext/arrow/converters.hpp
@@ -28,6 +28,7 @@
 
 namespace red_arrow {
   class ListArrayValueConverter;
+  class LargeListArrayValueConverter;
   class StructArrayValueConverter;
   class MapArrayValueConverter;
   class UnionArrayValueConverter;
@@ -38,6 +39,7 @@ namespace red_arrow {
     ArrayValueConverter()
       : decimal_buffer_(),
         list_array_value_converter_(nullptr),
+        large_list_array_value_converter_(nullptr),
         struct_array_value_converter_(nullptr),
         map_array_value_converter_(nullptr),
         union_array_value_converter_(nullptr),
@@ -45,11 +47,13 @@ namespace red_arrow {
     }
 
     inline void set_sub_value_converters(ListArrayValueConverter* 
list_array_value_converter,
+                                         LargeListArrayValueConverter* 
large_list_array_value_converter,
                                          StructArrayValueConverter* 
struct_array_value_converter,
                                          MapArrayValueConverter* 
map_array_value_converter,
                                          UnionArrayValueConverter* 
union_array_value_converter,
                                          DictionaryArrayValueConverter* 
dictionary_array_value_converter) {
       list_array_value_converter_ = list_array_value_converter;
+      large_list_array_value_converter_ = large_list_array_value_converter;
       struct_array_value_converter_ = struct_array_value_converter;
       map_array_value_converter_ = map_array_value_converter;
       union_array_value_converter_ = union_array_value_converter;
@@ -263,6 +267,9 @@ namespace red_arrow {
     VALUE convert(const arrow::ListArray& array,
                   const int64_t i);
 
+    VALUE convert(const arrow::LargeListArray& array,
+                  const int64_t i);
+
     VALUE convert(const arrow::StructArray& array,
                   const int64_t i);
 
@@ -298,6 +305,7 @@ namespace red_arrow {
 
     std::string decimal_buffer_;
     ListArrayValueConverter* list_array_value_converter_;
+    LargeListArrayValueConverter* large_list_array_value_converter_;
     StructArrayValueConverter* struct_array_value_converter_;
     MapArrayValueConverter* map_array_value_converter_;
     UnionArrayValueConverter* union_array_value_converter_;
@@ -359,6 +367,106 @@ namespace red_arrow {
     VISIT(DayTimeInterval)
     VISIT(MonthDayNanoInterval)
     VISIT(List)
+    VISIT(LargeList)
+    VISIT(Struct)
+    VISIT(Map)
+    VISIT(SparseUnion)
+    VISIT(DenseUnion)
+    VISIT(Dictionary)
+    VISIT(Decimal128)
+    VISIT(Decimal256)
+    // TODO
+    // VISIT(Extension)
+
+#undef VISIT
+
+  private:
+    template <typename ArrayType>
+    inline VALUE convert_value(const ArrayType& array,
+                               const int64_t i) {
+      return array_value_converter_->convert(array, i);
+    }
+
+    template <typename ArrayType>
+    arrow::Status visit_value(const ArrayType& array) {
+      if (array.null_count() > 0) {
+        for (int64_t i = 0; i < length_; ++i) {
+          auto value = Qnil;
+          if (!array.IsNull(i + offset_)) {
+            value = convert_value(array, i + offset_);
+          }
+          rb_ary_push(result_, value);
+        }
+      } else {
+        for (int64_t i = 0; i < length_; ++i) {
+          rb_ary_push(result_, convert_value(array, i + offset_));
+        }
+      }
+      return arrow::Status::OK();
+    }
+
+    ArrayValueConverter* array_value_converter_;
+    int32_t offset_;
+    int32_t length_;
+    VALUE result_;
+  };
+
+  class LargeListArrayValueConverter : public arrow::ArrayVisitor {
+  public:
+    explicit LargeListArrayValueConverter(ArrayValueConverter* converter)
+      : array_value_converter_(converter),
+        offset_(0),
+        length_(0),
+        result_(Qnil) {}
+
+    VALUE convert(const arrow::LargeListArray& array, const int64_t index) {
+      auto values = array.values().get();
+      auto offset_keep = offset_;
+      auto length_keep = length_;
+      offset_ = array.value_offset(index);
+      length_ = array.value_length(index);
+      auto result_keep = result_;
+      result_ = rb_ary_new_capa(length_);
+      check_status(values->Accept(this),
+                   "[raw-records][large-list-array]");
+      offset_ = offset_keep;
+      length_ = length_keep;
+      auto result_return = result_;
+      result_ = result_keep;
+      return result_return;
+    }
+
+#define VISIT(TYPE)                                                     \
+    arrow::Status Visit(const arrow::TYPE ## Array& array) override {   \
+      return visit_value(array);                                        \
+    }
+
+    VISIT(Null)
+    VISIT(Boolean)
+    VISIT(Int8)
+    VISIT(Int16)
+    VISIT(Int32)
+    VISIT(Int64)
+    VISIT(UInt8)
+    VISIT(UInt16)
+    VISIT(UInt32)
+    VISIT(UInt64)
+    VISIT(HalfFloat)
+    VISIT(Float)
+    VISIT(Double)
+    VISIT(Binary)
+    VISIT(String)
+    VISIT(FixedSizeBinary)
+    VISIT(Date32)
+    VISIT(Date64)
+    VISIT(Time32)
+    VISIT(Time64)
+    VISIT(Timestamp)
+    VISIT(MonthInterval)
+    VISIT(DayTimeInterval)
+    VISIT(MonthDayNanoInterval)
+    VISIT(List)
+    VISIT(LargeList)
     VISIT(Struct)
     VISIT(Map)
     VISIT(SparseUnion)
@@ -465,6 +573,7 @@ namespace red_arrow {
     VISIT(DayTimeInterval)
     VISIT(MonthDayNanoInterval)
     VISIT(List)
+    VISIT(LargeList)
     VISIT(Struct)
     VISIT(Map)
     VISIT(SparseUnion)
@@ -567,6 +676,7 @@ namespace red_arrow {
     VISIT(DayTimeInterval)
     VISIT(MonthDayNanoInterval)
     VISIT(List)
+    VISIT(LargeList)
     VISIT(Struct)
     VISIT(Map)
     VISIT(SparseUnion)
@@ -670,6 +780,7 @@ namespace red_arrow {
     VISIT(DayTimeInterval)
     VISIT(MonthDayNanoInterval)
     VISIT(List)
+    VISIT(LargeList)
     VISIT(Struct)
     VISIT(Map)
     VISIT(SparseUnion)
@@ -781,6 +892,7 @@ namespace red_arrow {
     VISIT(DayTimeInterval)
     VISIT(MonthDayNanoInterval)
     VISIT(List)
+    VISIT(LargeList)
     VISIT(Struct)
     VISIT(Map)
     VISIT(SparseUnion)
@@ -810,12 +922,14 @@ namespace red_arrow {
     explicit Converter()
       : array_value_converter_(),
         list_array_value_converter_(&array_value_converter_),
+        large_list_array_value_converter_(&array_value_converter_),
         struct_array_value_converter_(&array_value_converter_),
         map_array_value_converter_(&array_value_converter_),
         union_array_value_converter_(&array_value_converter_),
         dictionary_array_value_converter_(&array_value_converter_) {
       array_value_converter_.
         set_sub_value_converters(&list_array_value_converter_,
+                                 &large_list_array_value_converter_,
                                  &struct_array_value_converter_,
                                  &map_array_value_converter_,
                                  &union_array_value_converter_,
@@ -830,6 +944,7 @@ namespace red_arrow {
 
     ArrayValueConverter array_value_converter_;
     ListArrayValueConverter list_array_value_converter_;
+    LargeListArrayValueConverter large_list_array_value_converter_;
     StructArrayValueConverter struct_array_value_converter_;
     MapArrayValueConverter map_array_value_converter_;
     UnionArrayValueConverter union_array_value_converter_;
diff --git a/ruby/red-arrow/ext/arrow/values.cpp 
b/ruby/red-arrow/ext/arrow/values.cpp
index e412ce2273..cd92e04d56 100644
--- a/ruby/red-arrow/ext/arrow/values.cpp
+++ b/ruby/red-arrow/ext/arrow/values.cpp
@@ -80,6 +80,7 @@ namespace red_arrow {
       VISIT(DayTimeInterval)
       VISIT(MonthDayNanoInterval)
       VISIT(List)
+      VISIT(LargeList)
       VISIT(Struct)
       VISIT(Map)
       VISIT(SparseUnion)
diff --git a/ruby/red-arrow/lib/arrow/large-list-array-builder.rb 
b/ruby/red-arrow/lib/arrow/large-list-array-builder.rb
new file mode 100644
index 0000000000..4a4ee63d15
--- /dev/null
+++ b/ruby/red-arrow/lib/arrow/large-list-array-builder.rb
@@ -0,0 +1,29 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+module Arrow
+  class LargeListArrayBuilder
+    class << self
+      def build(data_type, values)
+        builder = new(data_type)
+        builder.build(values)
+      end
+    end
+
+    prepend ListValuesAppendable
+  end
+end
diff --git a/ruby/red-arrow/lib/arrow/large-list-data-type.rb 
b/ruby/red-arrow/lib/arrow/large-list-data-type.rb
new file mode 100644
index 0000000000..82e2bc6bd2
--- /dev/null
+++ b/ruby/red-arrow/lib/arrow/large-list-data-type.rb
@@ -0,0 +1,83 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+module Arrow
+  class LargeListDataType
+    include ListFieldResolvable
+
+    alias_method :initialize_raw, :initialize
+    private :initialize_raw
+
+    # Creates a new {Arrow::LargeListDataType}.
+    #
+    # @overload initialize(field)
+    #
+    #   @param field [Arrow::Field, Hash] The field of the large list
+    #     data type. You can also specify field description by `Hash`.
+    #
+    #     See {Arrow::Field.new} how to specify field description.
+    #
+    #   @example Create a large list data type with {Arrow::Field}
+    #     visible_field = Arrow::Field.new("visible", :boolean)
+    #     Arrow::LargeListDataType.new(visible_field)
+    #
+    #   @example Create a large list data type with field description
+    #     Arrow::LargeListDataType.new(name: "visible", type: :boolean)
+    #
+    # @overload initialize(description)
+    #
+    #   @param description [Hash] The description of the large list data
+    #     type. It must have `:field` value.
+    #
+    #   @option description [Arrow::Field, Hash] :field The field of
+    #     the large list data type. You can also specify field
+    #     description by `Hash`.
+    #
+    #     See {Arrow::Field.new} how to specify field description.
+    #
+    #   @example Create a large list data type with {Arrow::Field}
+    #     visible_field = Arrow::Field.new("visible", :boolean)
+    #     Arrow::LargeListDataType.new(field: visible_field)
+    #
+    #   @example Create a large list data type with field description
+    #     Arrow::LargeListDataType.new(field: {name: "visible", type: 
:boolean})
+    #
+    # @overload initialize(data_type)
+    #
+    #   @param data_type [Arrow::DataType, String, Symbol,
+    #     ::Array<String>, ::Array<Symbol>, Hash] The element data
+    #     type of the large list data type. A field is created with the
+    #     default name `"item"` from the data type automatically.
+    #
+    #     See {Arrow::DataType.resolve} how to specify data type.
+    #
+    #   @example Create a large list data type with {Arrow::DataType}
+    #     Arrow::LargeListDataType.new(Arrow::BooleanDataType.new)
+    #
+    #   @example Create a large list data type with data type name as String
+    #     Arrow::LargeListDataType.new("boolean")
+    #
+    #   @example Create a large list data type with data type name as Symbol
+    #     Arrow::LargeListDataType.new(:boolean)
+    #
+    #   @example Create a large list data type with data type as Array
+    #     Arrow::LargeListDataType.new([:time32, :milli])
+    def initialize(arg)
+      initialize_raw(resolve_field(arg))
+    end
+  end
+end
diff --git a/ruby/red-arrow/lib/arrow/libraries.rb 
b/ruby/red-arrow/lib/arrow/libraries.rb
index 7a1292744a..007d541423 100644
--- a/ruby/red-arrow/lib/arrow/libraries.rb
+++ b/ruby/red-arrow/lib/arrow/libraries.rb
@@ -21,6 +21,8 @@ require_relative "field-containable"
 require_relative "generic-filterable"
 require_relative "generic-takeable"
 require_relative "input-referable"
+require_relative "list-field-resolvable"
+require_relative "list-values-appendable"
 require_relative "record-containable"
 require_relative "symbol-values-appendable"
 
@@ -69,6 +71,8 @@ require_relative "group"
 require_relative "half-float"
 require_relative "half-float-array"
 require_relative "half-float-array-builder"
+require_relative "large-list-array-builder"
+require_relative "large-list-data-type"
 require_relative "list-array-builder"
 require_relative "list-data-type"
 require_relative "map-array"
diff --git a/ruby/red-arrow/lib/arrow/list-array-builder.rb 
b/ruby/red-arrow/lib/arrow/list-array-builder.rb
index d6975327b5..92c5c9368b 100644
--- a/ruby/red-arrow/lib/arrow/list-array-builder.rb
+++ b/ruby/red-arrow/lib/arrow/list-array-builder.rb
@@ -24,74 +24,6 @@ module Arrow
       end
     end
 
-    alias_method :append_value_raw, :append_value
-
-    # @overload append_value
-    #
-    #   Starts appending a list record. You also need to append list
-    #   value by {#value_builder}.
-    #
-    # @overload append_value(list)
-    #
-    #   Appends a list record including list value.
-    #
-    #   @param value [nil, ::Array] The list value of the record.
-    #
-    #     If this is `nil`, the list record is null.
-    #
-    #     If this is `Array`, it's the list value of the record.
-    #
-    # @since 0.12.0
-    def append_value(*args)
-      n_args = args.size
-
-      case n_args
-      when 0
-        append_value_raw
-      when 1
-        value = args[0]
-        case value
-        when nil
-          append_null
-        when ::Array
-          append_value_raw
-          return if value.empty?
-          @value_builder ||= value_builder
-          @value_builder.append(*value)
-        else
-          message = "list value must be nil or Array: #{value.inspect}"
-          raise ArgumentError, message
-        end
-      else
-        message = "wrong number of arguments (given #{n_args}, expected 0..1)"
-        raise ArgumentError, message
-      end
-    end
-
-    def append_values(lists, is_valids=nil)
-      if is_valids
-        is_valids.each_with_index do |is_valid, i|
-          if is_valid
-            append_value(lists[i])
-          else
-            append_null
-          end
-        end
-      else
-        lists.each do |list|
-          append_value(list)
-        end
-      end
-    end
-
-    # @since 0.12.0
-    def append(*values)
-      if values.empty?
-        # For backward compatibility
-        append_value
-      else
-        super
-      end
-    end
+    prepend ListValuesAppendable
   end
 end
diff --git a/ruby/red-arrow/lib/arrow/list-data-type.rb 
b/ruby/red-arrow/lib/arrow/list-data-type.rb
index 30c9cbdc70..2d524b071f 100644
--- a/ruby/red-arrow/lib/arrow/list-data-type.rb
+++ b/ruby/red-arrow/lib/arrow/list-data-type.rb
@@ -17,6 +17,8 @@
 
 module Arrow
   class ListDataType
+    include ListFieldResolvable
+
     alias_method :initialize_raw, :initialize
     private :initialize_raw
 
@@ -75,39 +77,7 @@ module Arrow
     #   @example Create a list data type with data type as Array
     #     Arrow::ListDataType.new([:time32, :milli])
     def initialize(arg)
-      data_type = resolve_data_type(arg)
-      if data_type
-        field = Field.new(default_field_name, data_type)
-      else
-        field = resolve_field(arg)
-      end
-      initialize_raw(field)
-    end
-
-    private
-    def resolve_data_type(arg)
-      case arg
-      when DataType, String, Symbol, ::Array
-        DataType.resolve(arg)
-      when Hash
-        return nil if arg[:name]
-        return nil unless arg[:type]
-        DataType.resolve(arg)
-      else
-        nil
-      end
-    end
-
-    def default_field_name
-      "item"
-    end
-
-    def resolve_field(arg)
-      if arg.is_a?(Hash) and arg.key?(:field)
-        description = arg
-        arg = description[:field]
-      end
-      arg
+      initialize_raw(resolve_field(arg))
     end
   end
 end
diff --git a/ruby/red-arrow/lib/arrow/list-field-resolvable.rb 
b/ruby/red-arrow/lib/arrow/list-field-resolvable.rb
new file mode 100644
index 0000000000..de97363d9f
--- /dev/null
+++ b/ruby/red-arrow/lib/arrow/list-field-resolvable.rb
@@ -0,0 +1,50 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+module Arrow
+  module ListFieldResolvable
+    private
+    def resolve_data_type(arg)
+      case arg
+      when DataType, String, Symbol, ::Array
+        DataType.resolve(arg)
+      when Hash
+        return nil if arg[:name]
+        return nil unless arg[:type]
+        DataType.resolve(arg)
+      else
+        nil
+      end
+    end
+
+    def default_field_name
+      "item"
+    end
+
+    def resolve_field(arg)
+      data_type = resolve_data_type(arg)
+      if data_type
+        Field.new(default_field_name, data_type)
+      elsif arg.is_a?(Hash) and arg.key?(:field)
+        description = arg
+        description[:field]
+      else
+        arg
+      end
+    end
+  end
+end
diff --git a/ruby/red-arrow/lib/arrow/list-array-builder.rb 
b/ruby/red-arrow/lib/arrow/list-values-appendable.rb
similarity index 90%
copy from ruby/red-arrow/lib/arrow/list-array-builder.rb
copy to ruby/red-arrow/lib/arrow/list-values-appendable.rb
index d6975327b5..cbf7f7be63 100644
--- a/ruby/red-arrow/lib/arrow/list-array-builder.rb
+++ b/ruby/red-arrow/lib/arrow/list-values-appendable.rb
@@ -16,16 +16,7 @@
 # under the License.
 
 module Arrow
-  class ListArrayBuilder
-    class << self
-      def build(data_type, values)
-        builder = new(data_type)
-        builder.build(values)
-      end
-    end
-
-    alias_method :append_value_raw, :append_value
-
+  module ListValuesAppendable
     # @overload append_value
     #
     #   Starts appending a list record. You also need to append list
@@ -47,14 +38,14 @@ module Arrow
 
       case n_args
       when 0
-        append_value_raw
+        super()
       when 1
         value = args[0]
         case value
         when nil
           append_null
         when ::Array
-          append_value_raw
+          super()
           return if value.empty?
           @value_builder ||= value_builder
           @value_builder.append(*value)

Reply via email to