You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@thrift.apache.org by "Dmytro Shteflyuk (Jira)" <ji...@apache.org> on 2026/10/22 22:58:00 UTC

[jira] [Assigned] (THRIFT-6446) Pure-Ruby struct writer fails on a set of lists

     [ https://issues.apache.org/jira/browse/THRIFT-6446?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Dmytro Shteflyuk reassigned THRIFT-6446:
----------------------------------------

    Assignee: Dmytro Shteflyuk

> Pure-Ruby struct writer fails on a set of lists
> -----------------------------------------------
>
>                 Key: THRIFT-6446
>                 URL: https://issues.apache.org/jira/browse/THRIFT-6446
>             Project: Thrift
>          Issue Type: Bug
>          Components: Ruby - Library
>    Affects Versions: 0.25.0
>            Reporter: Jens Geyer
>            Assignee: Dmytro Shteflyuk
>            Priority: Minor
>
> Without the {{thrift_native}} extension (pure Ruby, as on JRuby or when the extension is not built), writing a struct whose {{set<list<...>>}} field is not empty fails with a {{NoMethodError}}. The set branch of {{Thrift::Struct_Union#write_container}} iterates with a trailing comma in the block parameters, kept for the old Hash-style sets ([struct_union.rb:145|https://github.com/apache/thrift/blob/v0.25.0/lib/rb/lib/thrift/struct_union.rb#L145]):
> {code}
> value.each do |v,| # the , is to preserve compatibility with the old Hash-style sets
>   write_data(oprot, v, field[:element], remaining_depth)
> end
> {code}
> For an element that is an Array, that destructures the element, so only its first item reaches the list writer, which then fails on it.
> {code}
> struct S {
>   1: set<list<i32>> s
> }
> {code}
> {noformat}
> $ thrift --gen rb sets.thrift
> $ ruby -I lib/rb/lib -I gen-rb -e 'require "thrift"; require "sets_types"
> S.new(s: Set.new([[1, 2]])).write(Thrift::BinaryProtocol.new(Thrift::MemoryBufferTransport.new))'
> Unable to load thrift_native extension. Defaulting to pure Ruby libraries.
> lib/rb/lib/thrift/struct_union.rb:139:in `write_container': undefined method `each' for 1:Integer (NoMethodError)
> {noformat}
> With the native extension loaded, the same struct is written correctly. Sets of maps or of sets are not affected in pure Ruby either, since only Array elements are destructured. Reproduced with the 0.25.0 compiler and library on Ruby 3.2 and 4.0; the line is the same on master. Iterating a Hash-style set by its keys and any other set by element writes both a set of lists and a Hash-style set correctly in the example:
> {code}
> (value.is_a?(Hash) ? value.keys : value).each do |v|
>   write_data(oprot, v, field[:element], remaining_depth)
> end
> {code}
> _Drafted with AI assistance (Claude Opus 5.5)._



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)