From: "jeremyevans0 (Jeremy Evans) via ruby-core" Date: 2025-05-27T14:43:26+00:00 Subject: [ruby-core:122311] [Ruby Bug#21375] Set[] does not call #initialize Issue #21375 has been updated by jeremyevans0 (Jeremy Evans). nobu (Nobuyoshi Nakada) wrote in #note-1: > I'm not sure if it is intentional or not. It was intentional when I developed core Set. `Set.[]` takes different arguments than `Set#initialize`. `Array.[]` does not call `Array#initialize`, and `Hash.[]` does not call `Hash#initialize`, so there is precedent for the core collection classes to operate this way. `Set.[]` was not documented as calling `Set#initialize` previously, and there were no tests or specs for it. Relying on `Set.[]` calling `Set#initialize` was relying on undefined behavior. > If unintentional, this patch may fix it. > > ```diff > diff --git a/set.c b/set.c > index 8676c62cd35..c41781c446f 100644 > --- a/set.c > +++ b/set.c > @@ -409,13 +409,7 @@ static VALUE > set_s_create(int argc, VALUE *argv, VALUE klass) > { > VALUE set = set_alloc_with_size(klass, argc); > - set_table *table = RSET_TABLE(set); > - int i; > - > - for (i=0; i < argc; i++) { > - set_table_insert_wb(table, set, argv[i], NULL); > - } > - > + rb_obj_call_init(set, argc, argv); > return set; > } > > ``` I'm not sure whether this is correct. `#initialize` arguments are enumerables of elements, `.[]` arguments are elements. I think if we wanted to call `#initialize`, we would have to allocate an array for the elements, and pass that, which would reduce performance. ---------------------------------------- Bug #21375: Set[] does not call #initialize https://bugs.ruby-lang.org/issues/21375#change-113453 * Author: Ethan (Ethan -) * Status: Open * ruby -v: ruby 3.5.0dev (2025-05-26T17:42:35Z master 909a0daab6) +PRISM [x86_64-darwin22] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- I have a subclass of Set that overrides #initialize. Following #21216, .new does call #initialize but .[] does not. ```ruby class MySet < Set def initialize(enum = nil) compare_by_identity super end end MySet.new.compare_by_identity? # => true MySet[].compare_by_identity? # => false ``` -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/