Deprecate passing arguments to Set#to_set and Enumerable#to_set
Array#to_a, Hash#to_h, Enumerable#to_a, and Enumerable#to_h do not allow you to specify subclasses. This has undesired behavior when passing non-Set subclasses. All of these are currently allowed, and none make sense: ```ruby enum = [1,2,3].to_enum enum.to_set(Hash) enum.to_set(Struct.new("A", :a)) enum.to_set(ArgumentError) enum.to_set(Thread){} ``` Users who want to create instances of a subclass of Set from an enumerable should pass the enumerable to SetSubclass.new instead of using to_set.
This commit is contained in:
parent
2f80117ce4
commit
0b07d2a1e3
Notes:
git
2025-06-05 16:24:19 +00:00
@ -16792,6 +16792,7 @@ set.$(OBJEXT): $(top_srcdir)/internal/array.h
|
||||
set.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
|
||||
set.$(OBJEXT): $(top_srcdir)/internal/bits.h
|
||||
set.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||
set.$(OBJEXT): $(top_srcdir)/internal/error.h
|
||||
set.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||
set.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||
set.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||
@ -16801,6 +16802,7 @@ set.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||
set.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||
set.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
||||
set.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
|
||||
set.$(OBJEXT): $(top_srcdir)/internal/string.h
|
||||
set.$(OBJEXT): $(top_srcdir)/internal/symbol.h
|
||||
set.$(OBJEXT): $(top_srcdir)/internal/variable.h
|
||||
set.$(OBJEXT): $(top_srcdir)/internal/vm.h
|
||||
|
@ -28,7 +28,14 @@ end
|
||||
|
||||
module Enumerable
|
||||
# Makes a set from the enumerable object with given arguments.
|
||||
def to_set(klass = Set, *args, &block)
|
||||
# Passing arguments to this method is deprecated.
|
||||
def to_set(*args, &block)
|
||||
klass = if args.empty?
|
||||
Set
|
||||
else
|
||||
warn "passing arguments to Enumerable#to_set is deprecated", uplevel: 1
|
||||
args.shift
|
||||
end
|
||||
klass.new(self, *args, &block)
|
||||
end
|
||||
end
|
||||
|
2
set.c
2
set.c
@ -7,6 +7,7 @@
|
||||
#include "id.h"
|
||||
#include "internal.h"
|
||||
#include "internal/bits.h"
|
||||
#include "internal/error.h"
|
||||
#include "internal/hash.h"
|
||||
#include "internal/proc.h"
|
||||
#include "internal/sanitizers.h"
|
||||
@ -635,6 +636,7 @@ set_i_to_set(int argc, VALUE *argv, VALUE set)
|
||||
argc = 1;
|
||||
}
|
||||
else {
|
||||
rb_warn_deprecated("passing arguments to Set#to_set", NULL);
|
||||
klass = argv[0];
|
||||
argv[0] = set;
|
||||
}
|
||||
|
@ -11,10 +11,21 @@ describe "Enumerable#to_set" do
|
||||
[1, 2, 3].to_set { |x| x * x }.should == Set[1, 4, 9]
|
||||
end
|
||||
|
||||
it "instantiates an object of provided as the first argument set class" do
|
||||
set = [1, 2, 3].to_set(EnumerableSpecs::SetSubclass)
|
||||
set.should be_kind_of(EnumerableSpecs::SetSubclass)
|
||||
set.to_a.sort.should == [1, 2, 3]
|
||||
ruby_version_is "3.5" do
|
||||
it "instantiates an object of provided as the first argument set class" do
|
||||
set = nil
|
||||
proc{set = [1, 2, 3].to_set(EnumerableSpecs::SetSubclass)}.should complain(/Enumerable#to_set/)
|
||||
set.should be_kind_of(EnumerableSpecs::SetSubclass)
|
||||
set.to_a.sort.should == [1, 2, 3]
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is ""..."3.5" do
|
||||
it "instantiates an object of provided as the first argument set class" do
|
||||
set = [1, 2, 3].to_set(EnumerableSpecs::SetSubclass)
|
||||
set.should be_kind_of(EnumerableSpecs::SetSubclass)
|
||||
set.to_a.sort.should == [1, 2, 3]
|
||||
end
|
||||
end
|
||||
|
||||
it "does not need explicit `require 'set'`" do
|
||||
|
Loading…
x
Reference in New Issue
Block a user