From: "jeremyevans0 (Jeremy Evans) via ruby-core" Date: 2025-06-30T20:25:28+00:00 Subject: [ruby-core:122631] [Ruby Feature#21459] Add Set C-API Issue #21459 has been updated by jeremyevans0 (Jeremy Evans). Eregon (Benoit Daloze) wrote in #note-1: > jeremyevans0 (Jeremy Evans) wrote: > > I think this should allow extension libraries to start benefiting from core Set without having to resort to method calls (dangerous in an C extension as they could be redefined to return objects of an unexpected type). > > What would be the danger with that? > It could cause a NoMethodError or so, but that's fine. When you are using rb_funcall, you cannot rely on the type of returned objects. If you want to pass returned objects to other C-API functions, you need defensive type checks, or it can result in undefined behavior (including segfaults) depending on how the returned objects are used. Let's say you want to call the `Set#size` method and pass the result to `rb_fix2str`. If a user overrides the `Set#size` method to return an object of a different type, you get undefined behavior, as `rb_fix2str` does not perform type checks. By having an `rb_set_size` C-API function, you know what type will be returned. Having C-API functions for common methods is more efficient performance wise, and increases programmer happiness, since calling the functions is simpler than using rb_funcall. This is especially true in the `rb_set_foreach` case. Without `rb_set_foreach`, instead of passing a C function pointer, you would have to build a Ruby block in C that you could pass to `Set#each` or `Set#delete_if`. Passing a C function is also more flexible, since the same function can deal with both iteration and deletion. > IMO rb_funcall() is enough for this, and anyway needs to be used for Ruby version < 3.5. The idea that we shouldn't add this because it cannot be used on older Ruby versions is basically an argument against adding any feature at all. If we add this, code targeting Ruby 3.5+ can benefit from it, and eventually not working on versions older than Ruby 3.5 will be a non-issue. ---------------------------------------- Feature #21459: Add Set C-API https://bugs.ruby-lang.org/issues/21459#change-113870 * Author: jeremyevans0 (Jeremy Evans) * Status: Open ---------------------------------------- I would like to add a minimal C-API for Set: ```c void rb_set_foreach(VALUE set, int (*func)(VALUE element, VALUE arg), VALUE arg); VALUE rb_set_new(void); VALUE rb_set_new_capa(unsigned long capa); bool rb_set_lookup(VALUE set, VALUE element); bool rb_set_add(VALUE set, VALUE element); VALUE rb_set_clear(VALUE set); bool rb_set_delete(VALUE set, VALUE element); size_t rb_set_size(VALUE set); ``` I think this should allow extension libraries to start benefiting from core Set without having to resort to method calls (dangerous in an C extension as they could be redefined to return objects of an unexpected type). I've submitted a pull request for this: https://github.com/ruby/ruby/pull/13735 -- 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/