Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove compile-time error for Range#size, #each, #sample #13278

Merged
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
62 changes: 44 additions & 18 deletions spec/std/range_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ describe "Range" do
end
end

describe "each" do
describe "#each" do
it "gives correct values with inclusive range" do
range = -1..3
arr = [] of Int32
Expand Down Expand Up @@ -236,10 +236,14 @@ describe "Range" do
end

it "raises on beginless" do
range = (true ? nil : 1)..4
expect_raises(ArgumentError, "Can't each beginless range") do
range.each { }
(..4).each { }
end
typeof((..4).each { |x| break x }).should eq Nil
expect_raises(ArgumentError, "Can't each beginless range") do
(nil.as(Int32?)..4).each { }
end
typeof((nil.as(Int32?)..4).each { |x| break x }).should eq Int32?
end

it "doesn't have Nil as a type for endless each" do
Expand All @@ -251,7 +255,7 @@ describe "Range" do
end
end

describe "reverse_each" do
describe "#reverse_each" do
it "gives correct values with inclusive range" do
range = 'a'..'c'
arr = [] of Char
Expand All @@ -274,9 +278,11 @@ describe "Range" do
end

it "raises on endless range" do
range = (3..(true ? nil : 1))
expect_raises(ArgumentError, "Can't reverse_each endless range") do
range.reverse_each { }
(3..).reverse_each { }
end
expect_raises(ArgumentError, "Can't reverse_each endless range") do
(3..nil.as(Int32?)).reverse_each { }
end
end

Expand All @@ -291,7 +297,7 @@ describe "Range" do
end
end

describe "each iterator" do
describe "#each iterator" do
it "does next with inclusive range" do
a = 1..3
iter = a.each
Expand All @@ -317,9 +323,11 @@ describe "Range" do
end

it "raises on beginless range" do
r = (true ? nil : 1)..3
expect_raises(ArgumentError, "Can't each beginless range") do
r.each
(..3).each
end
expect_raises(ArgumentError, "Can't each beginless range") do
(nil.as(Int32?)..3).each
end
end

Expand All @@ -344,7 +352,7 @@ describe "Range" do
end
end

describe "reverse_each iterator" do
describe "#reverse_each iterator" do
it "does next with inclusive range" do
a = 1..3
iter = a.reverse_each
Expand Down Expand Up @@ -393,21 +401,33 @@ describe "Range" do

it "raises on endless range" do
expect_raises(ArgumentError, "Can't reverse_each endless range") do
(1..(true ? nil : 1)).reverse_each
(1..).reverse_each
end
expect_raises(ArgumentError, "Can't reverse_each endless range") do
(1..nil.as(Int32?)).reverse_each
end
end
end

describe "sample" do
describe "#sample" do
it "raises on open range" do
expect_raises(ArgumentError, "Can't sample an open range") do
(1..(true ? nil : 1)).sample
(1..).sample
end
expect_raises(ArgumentError, "Can't sample an open range") do
(1..nil.as(Int32?)).sample
end
expect_raises(ArgumentError, "Can't sample an open range") do
(..1).sample
end
expect_raises(ArgumentError, "Can't sample an open range") do
(nil.as(Int32?)..1).sample
end
expect_raises(ArgumentError, "Can't sample an open range") do
((true ? nil : 1)..1).sample
(..).sample
end
expect_raises(ArgumentError, "Can't sample an open range") do
((true ? nil : 1)..(true ? nil : 1)).sample
(nil.as(Int32?)..nil.as(Int32?)).sample
end
end

Expand Down Expand Up @@ -648,7 +668,7 @@ describe "Range" do
end
end

describe "size" do
describe "#size" do
it "optimizes for int range" do
(5..12).size.should eq(8)
(5...12).size.should eq(7)
Expand All @@ -661,13 +681,19 @@ describe "Range" do

it "raises on beginless range" do
expect_raises(ArgumentError, "Can't calculate size of an open range") do
((true ? nil : 1)..3).size
(..3).size
end
expect_raises(ArgumentError, "Can't calculate size of an open range") do
(nil.as(Int32?)..3).size
end
end

it "raises on endless range" do
expect_raises(ArgumentError, "Can't calculate size of an open range") do
(3..(true ? nil : 1)).size
(3..).size
end
expect_raises(ArgumentError, "Can't calculate size of an open range") do
(3..nil.as(Int32?)).size
end
end
end
Expand Down
28 changes: 0 additions & 28 deletions src/range.cr
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,6 @@ struct Range(B, E)
# # prints: 10 11 12 13 14 15
# ```
def each(&) : Nil
{% if B == Nil %}
{% raise "Can't each beginless range" %}
{% end %}

current = @begin
if current.nil?
raise ArgumentError.new("Can't each beginless range")
Expand Down Expand Up @@ -142,10 +138,6 @@ struct Range(B, E)
# (1..3).each.skip(1).to_a # => [2, 3]
# ```
def each
{% if B == Nil %}
{% raise "Can't each beginless range" %}
{% end %}

if @begin.nil?
raise ArgumentError.new("Can't each beginless range")
end
Expand All @@ -161,10 +153,6 @@ struct Range(B, E)
# # prints: 14 13 12 11 10
# ```
def reverse_each(&) : Nil
{% if E == Nil %}
{% raise "Can't reverse_each endless range" %}
{% end %}

end_value = @end
if end_value.nil?
raise ArgumentError.new("Can't reverse_each endless range")
Expand Down Expand Up @@ -196,10 +184,6 @@ struct Range(B, E)
# (1..3).reverse_each.skip(1).to_a # => [2, 1]
# ```
def reverse_each
{% if E == Nil %}
{% raise "Can't reverse_each endless range" %}
{% end %}

if @end.nil?
raise ArgumentError.new("Can't reverse_each endless range")
end
Expand Down Expand Up @@ -363,10 +347,6 @@ struct Range(B, E)
#
# Raises `ArgumentError` if `self` is an open range.
def sample(random : Random = Random::DEFAULT)
{% if B == Nil || E == Nil %}
{% raise "Can't sample an open range" %}
{% end %}

{% if B < Int && E < Int %}
random.rand(self)
{% elsif B < Float && E < Float %}
Expand All @@ -391,10 +371,6 @@ struct Range(B, E)
# once. Thus, *random* will be left in a different state compared to the
# implementation in `Enumerable`.
def sample(n : Int, random = Random::DEFAULT)
{% if B == Nil || E == Nil %}
{% raise "Can't sample an open range" %}
{% end %}

if self.begin.nil? || self.end.nil?
raise ArgumentError.new("Can't sample an open range")
end
Expand Down Expand Up @@ -507,10 +483,6 @@ struct Range(B, E)
# (3...8).size # => 5
# ```
def size
{% if B == Nil || E == Nil %}
{% raise "Can't calculate size of an open range" %}
{% end %}

b = self.begin
e = self.end

Expand Down