Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .rdoc_options
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ rdoc_include:

exclude:
- \.gemspec\z
- lib/set/subclass_compatible.rb

generator_name: aliki

Expand Down
11 changes: 8 additions & 3 deletions defs/jit.mk
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# Make recipes that deal with the rust code of YJIT and ZJIT.
#
# $(gnumake_recursive) adds the '+' prefix to pass down GNU make's
# jobserver resources to cargo/rustc as rust-lang.org recommends.
# Without it, certain make version trigger a warning. It does not
# add the prefix when `make --dry-run` so dry runs are indeed dry.

ifneq ($(JIT_CARGO_SUPPORT),no)

Expand All @@ -25,7 +30,7 @@ $(RUST_LIB): $(srcdir)/ruby.rs
elif [ '$(YJIT_SUPPORT)' != no ]; then \
echo 'building YJIT ($(JIT_CARGO_SUPPORT) mode)'; \
fi
+$(Q)CARGO_TARGET_DIR='$(CARGO_TARGET_DIR)' \
$(gnumake_recursive)$(Q)CARGO_TARGET_DIR='$(CARGO_TARGET_DIR)' \
CARGO_TERM_PROGRESS_WHEN='never' \
MACOSX_DEPLOYMENT_TARGET=11.0 \
$(CARGO) $(CARGO_VERBOSE) build --manifest-path '$(top_srcdir)/Cargo.toml' $(CARGO_BUILD_ARGS)
Expand All @@ -34,7 +39,7 @@ else ifneq ($(strip $(RLIB_DIR)),) # combo build

$(RUST_LIB): $(srcdir)/ruby.rs
$(ECHO) 'building $(@F)'
$(Q) $(RUSTC) --edition=2024 \
$(gnumake_recursive)$(Q) $(RUSTC) --edition=2024 \
'-L$(@D)' \
--extern=yjit \
--extern=zjit \
Expand All @@ -50,7 +55,7 @@ $(YJIT_RLIB): $(JIT_RLIB)
$(ZJIT_RLIB): $(JIT_RLIB)
$(JIT_RLIB):
$(ECHO) 'building $(@F)'
$(Q) $(RUSTC) --crate-name=jit \
$(gnumake_recursive)$(Q) $(RUSTC) --crate-name=jit \
--edition=2024 \
$(JIT_RUST_FLAGS) \
'--out-dir=$(@D)' \
Expand Down
32 changes: 12 additions & 20 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1537,34 +1537,26 @@ os_obj_of(VALUE of)
* Ruby process. If <i>module</i> is specified, calls the block
* for only those classes or modules that match (or are a subclass of)
* <i>module</i>. Returns the number of objects found. Immediate
* objects (<code>Fixnum</code>s, <code>Symbol</code>s
* <code>true</code>, <code>false</code>, and <code>nil</code>) are
* never returned. In the example below, #each_object returns both
* the numbers we defined and several constants defined in the Math
* module.
* objects (such as <code>Fixnum</code>s, static <code>Symbol</code>s
* <code>true</code>, <code>false</code> and <code>nil</code>) are
* never returned.
*
* If no block is given, an enumerator is returned instead.
*
* a = 102.7
* b = 95 # Won't be returned
* c = 12345678987654321
* count = ObjectSpace.each_object(Numeric) {|x| p x }
* Job = Class.new
* jobs = [Job.new, Job.new]
* count = ObjectSpace.each_object(Job) {|x| p x }
* puts "Total count: #{count}"
*
* <em>produces:</em>
*
* 12345678987654321
* 102.7
* 2.71828182845905
* 3.14159265358979
* 2.22044604925031e-16
* 1.7976931348623157e+308
* 2.2250738585072e-308
* Total count: 7
* #<Job:0x000000011d6cbbf0>
* #<Job:0x000000011d6cbc68>
* Total count: 2
*
* Due to a current known Ractor implementation issue, this method will not yield
* Ractor-unshareable objects in multi-Ractor mode (when
* <code>Ractor.new</code> has been called within the process at least once).
* Due to a current Ractor implementation issue, this method does not yield
* Ractor-unshareable objects when the process is in multi-Ractor mode. Multi-ractor
* mode is enabled when <code>Ractor.new</code> has been called for the first time.
* See https://bugs.ruby-lang.org/issues/19387 for more information.
*
* a = 12345678987654321 # shareable
Expand Down
2 changes: 1 addition & 1 deletion include/ruby/internal/ctype.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ RBIMPL_ATTR_ARTIFICIAL()
* Our own locale-insensitive version of `tolower(3)`.
*
* @param[in] c Byte in question to convert.
* @retval c The byte is not listed in in IEEE 1003.1 section
* @retval c The byte is not listed in IEEE 1003.1 section
* 7.3.1.1 "upper".
* @retval otherwise Byte converted using the map defined in IEEE 1003.1
* section 7.3.1 "tolower".
Expand Down
2 changes: 1 addition & 1 deletion include/ruby/internal/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ ID rb_check_id(volatile VALUE *namep);
*
* :FIXME: Can anyone tell us what is the difference between this one and
* rb_intern_str()? As far as @shyouhei reads the implementation it seems what
* rb_to_id() does is is just waste some CPU time, then call rb_intern_str().
* rb_to_id() does is just waste some CPU time, then call rb_intern_str().
* He hopes he is wrong.
*/
ID rb_to_id(VALUE str);
Expand Down
7 changes: 6 additions & 1 deletion ractor_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,12 @@ ractor_sync_free(rb_ractor_t *r)
static size_t
ractor_sync_memsize(const rb_ractor_t *r)
{
return st_table_size(r->sync.ports);
if (r->sync.ports) {
return st_table_size(r->sync.ports);
}
else {
return 0;
}
}

static void
Expand Down
139 changes: 84 additions & 55 deletions set.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,11 +495,11 @@ set_initialize_with_block(RB_BLOCK_CALL_FUNC_ARGLIST(i, set))
* If a block is given, the elements of enum are preprocessed by the
* given block.
*
* Set.new([1, 2]) #=> #<Set: {1, 2}>
* Set.new([1, 2, 1]) #=> #<Set: {1, 2}>
* Set.new([1, 'c', :s]) #=> #<Set: {1, "c", :s}>
* Set.new(1..5) #=> #<Set: {1, 2, 3, 4, 5}>
* Set.new([1, 2, 3]) { |x| x * x } #=> #<Set: {1, 4, 9}>
* Set.new([1, 2]) #=> Set[1, 2]
* Set.new([1, 2, 1]) #=> Set[1, 2]
* Set.new([1, 'c', :s]) #=> Set[1, "c", :s]
* Set.new(1..5) #=> Set[1, 2, 3, 4, 5]
* Set.new([1, 2, 3]) { |x| x * x } #=> Set[1, 4, 9]
*/
static VALUE
set_i_initialize(int argc, VALUE *argv, VALUE set)
Expand Down Expand Up @@ -595,11 +595,11 @@ set_inspect(VALUE set, VALUE dummy, int recur)
* Returns a new string containing the set entries:
*
* s = Set.new
* s.inspect # => "#<Set: {}>"
* s.inspect # => "Set[]"
* s.add(1)
* s.inspect # => "#<Set: {1}>"
* s.inspect # => "Set[1]"
* s.add(2)
* s.inspect # => "#<Set: {1, 2}>"
* s.inspect # => "Set[1, 2]"
*
* Related: see {Methods for Converting}[rdoc-ref:Set@Methods+for+Converting].
*/
Expand Down Expand Up @@ -650,11 +650,11 @@ set_i_to_a(VALUE set)
* call-seq:
* to_set(klass = Set, *args, &block) -> self or new_set
*
* Returns self if receiver is an instance of +Set+ and no arguments or
* block are given. Otherwise, converts the set to another with
* <tt>klass.new(self, *args, &block)</tt>.
* Without arguments, returns +self+ (for duck-typing in methods that
* accept "set, or set-convertible" arguments).
*
* In subclasses, returns `klass.new(self, *args, &block)` unless overridden.
* A form with arguments is _deprecated_. It converts the set to another
* with <tt>klass.new(self, *args, &block)</tt>.
*/
static VALUE
set_i_to_set(int argc, VALUE *argv, VALUE set)
Expand Down Expand Up @@ -700,9 +700,9 @@ set_i_join(int argc, VALUE *argv, VALUE set)
* Adds the given object to the set and returns self. Use `merge` to
* add many elements at once.
*
* Set[1, 2].add(3) #=> #<Set: {1, 2, 3}>
* Set[1, 2].add([3, 4]) #=> #<Set: {1, 2, [3, 4]}>
* Set[1, 2].add(2) #=> #<Set: {1, 2}>
* Set[1, 2].add(3) #=> Set[1, 2, 3]
* Set[1, 2].add([3, 4]) #=> Set[1, 2, [3, 4]]
* Set[1, 2].add(2) #=> Set[1, 2]
*/
static VALUE
set_i_add(VALUE set, VALUE item)
Expand All @@ -726,8 +726,8 @@ set_i_add(VALUE set, VALUE item)
* Adds the given object to the set and returns self. If the object is
* already in the set, returns nil.
*
* Set[1, 2].add?(3) #=> #<Set: {1, 2, 3}>
* Set[1, 2].add?([3, 4]) #=> #<Set: {1, 2, [3, 4]}>
* Set[1, 2].add?(3) #=> Set[1, 2, 3]
* Set[1, 2].add?([3, 4]) #=> Set[1, 2, [3, 4]]
* Set[1, 2].add?(2) #=> nil
*/
static VALUE
Expand Down Expand Up @@ -856,9 +856,9 @@ set_classify_i(st_data_t key, st_data_t tmp)
*
* files = Set.new(Dir.glob("*.rb"))
* hash = files.classify { |f| File.mtime(f).year }
* hash #=> {2000 => #<Set: {"a.rb", "b.rb"}>,
* # 2001 => #<Set: {"c.rb", "d.rb", "e.rb"}>,
* # 2002 => #<Set: {"f.rb"}>}
* hash #=> {2000 => Set["a.rb", "b.rb"],
* # 2001 => Set["c.rb", "d.rb", "e.rb"],
* # 2002 => Set["f.rb"]}
*
* Returns an enumerator if no block is given.
*/
Expand Down Expand Up @@ -959,10 +959,10 @@ static void set_merge_enum_into(VALUE set, VALUE arg);
*
* numbers = Set[1, 3, 4, 6, 9, 10, 11]
* set = numbers.divide { |i,j| (i - j).abs == 1 }
* set #=> #<Set: {#<Set: {1}>,
* # #<Set: {3, 4}>,
* # #<Set: {6}>}>
* # #<Set: {9, 10, 11}>,
* set #=> Set[Set[1],
* # Set[3, 4],
* # Set[6],
* # Set[9, 10, 11]]
*
* Returns an enumerator if no block is given.
*/
Expand Down Expand Up @@ -993,9 +993,9 @@ set_clear_i(st_data_t key, st_data_t dummy)
*
* Removes all elements and returns self.
*
* set = Set[1, 'c', :s] #=> #<Set: {1, "c", :s}>
* set.clear #=> #<Set: {}>
* set #=> #<Set: {}>
* set = Set[1, 'c', :s] #=> Set[1, "c", :s]
* set.clear #=> Set[]
* set #=> Set[]
*/
static VALUE
set_i_clear(VALUE set)
Expand Down Expand Up @@ -1043,8 +1043,8 @@ set_intersection_block(RB_BLOCK_CALL_FUNC_ARGLIST(i, data))
* Returns a new set containing elements common to the set and the given
* enumerable object.
*
* Set[1, 3, 5] & Set[3, 2, 1] #=> #<Set: {3, 1}>
* Set['a', 'b', 'z'] & ['a', 'b', 'c'] #=> #<Set: {"a", "b"}>
* Set[1, 3, 5] & Set[3, 2, 1] #=> Set[3, 1]
* Set['a', 'b', 'z'] & ['a', 'b', 'c'] #=> Set["a", "b"]
*/
static VALUE
set_i_intersection(VALUE set, VALUE other)
Expand Down Expand Up @@ -1285,8 +1285,8 @@ set_xor_i(st_data_t key, st_data_t data)
* given enumerable object. <tt>(set ^ enum)</tt> is equivalent to
* <tt>((set | enum) - (set & enum))</tt>.
*
* Set[1, 2] ^ Set[2, 3] #=> #<Set: {3, 1}>
* Set[1, 'b', 'c'] ^ ['b', 'd'] #=> #<Set: {"d", 1, "c"}>
* Set[1, 2] ^ Set[2, 3] #=> Set[3, 1]
* Set[1, 'b', 'c'] ^ ['b', 'd'] #=> Set["d", 1, "c"]
*/
static VALUE
set_i_xor(VALUE set, VALUE other)
Expand All @@ -1312,8 +1312,8 @@ set_i_xor(VALUE set, VALUE other)
* Returns a new set built by merging the set and the elements of the
* given enumerable object.
*
* Set[1, 2, 3] | Set[2, 4, 5] #=> #<Set: {1, 2, 3, 4, 5}>
* Set[1, 5, 'z'] | (1..6) #=> #<Set: {1, 5, "z", 2, 3, 4, 6}>
* Set[1, 2, 3] | Set[2, 4, 5] #=> Set[1, 2, 3, 4, 5]
* Set[1, 5, 'z'] | (1..6) #=> Set[1, 5, "z", 2, 3, 4, 6]
*/
static VALUE
set_i_union(VALUE set, VALUE other)
Expand Down Expand Up @@ -1371,8 +1371,8 @@ set_i_subtract(VALUE set, VALUE other)
* Returns a new set built by duplicating the set, removing every
* element that appears in the given enumerable object.
*
* Set[1, 3, 5] - Set[1, 5] #=> #<Set: {3}>
* Set['a', 'b', 'z'] - ['a', 'c'] #=> #<Set: {"b", "z"}>
* Set[1, 3, 5] - Set[1, 5] #=> Set[3]
* Set['a', 'b', 'z'] - ['a', 'c'] #=> Set["b", "z"]
*/
static VALUE
set_i_difference(VALUE set, VALUE other)
Expand Down Expand Up @@ -1488,9 +1488,9 @@ set_i_select(VALUE set)
* Replaces the contents of the set with the contents of the given
* enumerable object and returns self.
*
* set = Set[1, 'c', :s] #=> #<Set: {1, "c", :s}>
* set.replace([1, 2]) #=> #<Set: {1, 2}>
* set #=> #<Set: {1, 2}>
* set = Set[1, 'c', :s] #=> Set[1, "c", :s]
* set.replace([1, 2]) #=> Set[1, 2]
* set #=> Set[1, 2]
*/
static VALUE
set_i_replace(VALUE set, VALUE other)
Expand Down Expand Up @@ -1766,7 +1766,7 @@ set_i_disjoint(VALUE set, VALUE other)
* set <=> other -> -1, 0, 1, or nil
*
* Returns 0 if the set are equal, -1 / 1 if the set is a
* proper subset / superset of the given set, or or nil if
* proper subset / superset of the given set, or nil if
* they both have unique elements.
*/
static VALUE
Expand Down Expand Up @@ -1992,10 +1992,10 @@ rb_set_size(VALUE set)
* duplicates. It is a hybrid of Array's intuitive inter-operation
* facilities and Hash's fast lookup.
*
* Set is easy to use with Enumerable objects (implementing `each`).
* Set is easy to use with Enumerable objects (implementing #each).
* Most of the initializer methods and binary operators accept generic
* Enumerable objects besides sets and arrays. An Enumerable object
* can be converted to Set using the `to_set` method.
* can be converted to Set using the +to_set+ method.
*
* Set uses a data structure similar to Hash for storage, except that
* it only has keys and no values.
Expand All @@ -2019,21 +2019,51 @@ rb_set_size(VALUE set)
*
* == Example
*
* s1 = Set[1, 2] #=> #<Set: {1, 2}>
* s2 = [1, 2].to_set #=> #<Set: {1, 2}>
* s1 = Set[1, 2] #=> Set[1, 2]
* s2 = [1, 2].to_set #=> Set[1, 2]
* s1 == s2 #=> true
* s1.add("foo") #=> #<Set: {1, 2, "foo"}>
* s1.merge([2, 6]) #=> #<Set: {1, 2, "foo", 6}>
* s1.add("foo") #=> Set[1, 2, "foo"]
* s1.merge([2, 6]) #=> Set[1, 2, "foo", 6]
* s1.subset?(s2) #=> false
* s2.subset?(s1) #=> true
*
* == Contact
*
* - Akinori MUSHA <knu@iDaemons.org> (current maintainer)
*
* == What's Here
* == Inheriting from \Set
*
* First, what's elsewhere. \Class \Set:
* Before Ruby 4.0 (released December 2025), \Set had a different, less
* efficient implementation. It was reimplemented in C, and the behavior
* of some of the core methods were adjusted.
*
* To keep backward compatibility, when a class is inherited from \Set,
* additional module +Set::SubclassCompatible+ is included, which makes
* the inherited class behavior, as well as internal method names,
* closer to what it was before Ruby 4.0.
*
* It can be easily seen, for example, in the #inspect method behavior:
*
* p Set[1, 2, 3]
* # prints "Set[1, 2, 3]"
*
* class MySet < Set
* end
* p MySet[1, 2, 3]
* # prints "#<MySet: {1, 2, 3}>", like it was in Ruby 3.4
*
* For new code, if backward compatibility is not necessary,
* it is recommended to instead inherit from +Set::CoreSet+, which
* avoids including the "compatibility" layer:
*
* class MyCoreSet < Set::CoreSet
* end
* p MyCoreSet[1, 2, 3]
* # prints "MyCoreSet[1, 2, 3]"
*
* == Set's methods
*
* First, what's elsewhere. \Class \Set:
*
* - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
* - Includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here],
Expand All @@ -2045,16 +2075,15 @@ rb_set_size(VALUE set)
*
* Here, class \Set provides methods that are useful for:
*
* - {Creating an Array}[rdoc-ref:Array@Methods+for+Creating+an+Array]
* - {Creating a Set}[rdoc-ref:Set@Methods+for+Creating+a+Set]
* - {Set Operations}[rdoc-ref:Set@Methods+for+Set+Operations]
* - {Comparing}[rdoc-ref:Array@Methods+for+Comparing]
* - {Querying}[rdoc-ref:Array@Methods+for+Querying]
* - {Assigning}[rdoc-ref:Array@Methods+for+Assigning]
* - {Deleting}[rdoc-ref:Array@Methods+for+Deleting]
* - {Converting}[rdoc-ref:Array@Methods+for+Converting]
* - {Iterating}[rdoc-ref:Array@Methods+for+Iterating]
* - {And more....}[rdoc-ref:Array@Other+Methods]
* - {Comparing}[rdoc-ref:Set@Methods+for+Comparing]
* - {Querying}[rdoc-ref:Set@Methods+for+Querying]
* - {Assigning}[rdoc-ref:Set@Methods+for+Assigning]
* - {Deleting}[rdoc-ref:Set@Methods+for+Deleting]
* - {Converting}[rdoc-ref:Set@Methods+for+Converting]
* - {Iterating}[rdoc-ref:Set@Methods+for+Iterating]
* - {And more....}[rdoc-ref:Set@Other+Methods]
*
* === Methods for Creating a \Set
*
Expand Down
Loading