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

add spec for Array can be sliced with Enumerator::ArithmeticSequence #857

Merged

Conversation

lxxxvi
Copy link
Contributor

@lxxxvi lxxxvi commented Oct 6, 2021

Hello 👋

Today I'll try to cover this from #823 :

(Array) Can be sliced with Enumerator::ArithmeticSequence

Thank you for your feedback.

Copy link
Member

@eregon eregon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, looks great!

core/array/shared/slice.rb Outdated Show resolved Hide resolved
core/array/shared/slice.rb Outdated Show resolved Hide resolved
@lxxxvi
Copy link
Contributor Author

lxxxvi commented Oct 6, 2021

@eregon You made me overdo it 😂

I was playing around with almost any combinations of (start..end).step(step) and (start...end).step(step) (excluding the end value), where:

  • start : nil | 0 | 1 | 2 | [negative number]
  • end : nil | 0 | -1 | -2 | [positive number]
  • step : 1 | 2 | 10 | -1 | -2 | -10

Then I learned that Enumerator::ArithmeticSequence allows "inverted ranges", like (3..1).step(1) or (3..1).step(-1), which made it even more confusing.

I ended up with many constellations, some of which broke my brain, particularly where steps are negative.

For example (the last one only):

# @array = [0, 1, 2, 3, 4, 5]
@array.send(@method, eval("(2..).step(-1)")).should == [2, 1, 0]
@array.send(@method, eval("(2..).step(-2)")).should == [2, 0]
@array.send(@method, eval("(2..).step(-10)")).should == [0]                   # ??? I would have expected [2]

The same with entire blocks

it "has beginless range and negative steps" {}
it "has inverted closed range and negative steps" {}

Now, I have three questions for you:

  1. Do expected values in the specs mentioned above make sense to you?
  2. Can we clean out some specs?
  3. Are you satisfied with the grouping of the specs, or do you want me to regroup them?

Regarding the clean out:

I think we can remove all assertions where the comment says:

  • # start and end with 0
  • # start with positive index, end with negative index
  • # start with negative index, end with positive index
  • # start with negative index, end with negative index

because I don't think they add value to the specs, what do you think?

@lxxxvi lxxxvi changed the title add spec for Array can be sliced with Enumerator::ArithmeticSequence WIP: add spec for Array can be sliced with Enumerator::ArithmeticSequence Oct 6, 2021
@eregon
Copy link
Member

eregon commented Oct 7, 2021

@array.send(@method, eval("(2..).step(-10)")).should == [0]                   # ??? I would have expected [2]

does seem weird, could you report it to bugs.ruby-lang.org/?

@eregon
Copy link
Member

eregon commented Oct 7, 2021

😆 I was just asking to split in two, but more coverage is always welcome :)

@eregon
Copy link
Member

eregon commented Oct 7, 2021

Copy link
Member

@eregon eregon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because I don't think they add value to the specs, what do you think?

I think they still increase coverage, and they run fast so I would keep them.

For all the ???, please report them and for now let's exclude those specs from this PR.
But please keep the current state on some other branch as they could be useful later on.
Maybe the behavior is actually intended for some of them although it's clearly very surprising to me too.


@array.send(@method, eval("(2..).step(-1)")).should == [2, 1, 0]
@array.send(@method, eval("(2..).step(-2)")).should == [2, 0]
@array.send(@method, eval("(2..).step(-10)")).should == [0] # ???
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it's weird, please report it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My version produced:

$ ./ruby --disable-gems -e "p [0, 1, 2, 3, 4, 5][(2..).step(-10)]"
[2]

(which seems reasonable, right?.. just the first one—at idx 2, then no more available items)


@array.send(@method, eval("(-3..).step(-1)")).should == [3, 2, 1, 0]
@array.send(@method, eval("(-3..).step(-2)")).should == [3, 1]
@array.send(@method, eval("(-3..).step(-10)")).should == [0] # ???
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it's weird, please report it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mine was:

$ ./ruby --disable-gems -e "p [0, 1, 2, 3, 4, 5][(-3..).step(-10)]"
[3]

@array.send(@method, eval("(-3..).step(-10)")).should == [0] # ???
end

# ????????
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it's weird, please report it

# ????????
it "has inverted closed range and negative steps" do
# start and end with positive index
@array.send(@method, eval("(3..1).step(-1)")).should == [3, 2, 1]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds reasonable

it "has inverted closed range and negative steps" do
# start and end with positive index
@array.send(@method, eval("(3..1).step(-1)")).should == [3, 2, 1]
@array.send(@method, eval("(3...1).step(-1)")).should == [2, 1]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it's weird, please report it. the 1 should be excluded, not the 3.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mine was

$ ./ruby --disable-gems -e "p [0, 1, 2, 3, 4, 5][(3...1).step(-1)]"
[3, 2]

@eregon
Copy link
Member

eregon commented Oct 7, 2021

@zverok @mrkn Could you take a look at the cases marked with ??? and see if they make sense to you or if they are bugs?

Copy link
Contributor

@zverok zverok left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments. In general, I agree that most of what's marked with ??? is weird/should be reported as bugs :)


@array.send(@method, eval("(2..).step(-1)")).should == [2, 1, 0]
@array.send(@method, eval("(2..).step(-2)")).should == [2, 0]
@array.send(@method, eval("(2..).step(-10)")).should == [0] # ???
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My version produced:

$ ./ruby --disable-gems -e "p [0, 1, 2, 3, 4, 5][(2..).step(-10)]"
[2]

(which seems reasonable, right?.. just the first one—at idx 2, then no more available items)


@array.send(@method, eval("(-3..).step(-1)")).should == [3, 2, 1, 0]
@array.send(@method, eval("(-3..).step(-2)")).should == [3, 1]
@array.send(@method, eval("(-3..).step(-10)")).should == [0] # ???
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mine was:

$ ./ruby --disable-gems -e "p [0, 1, 2, 3, 4, 5][(-3..).step(-10)]"
[3]

# ????????
it "has beginless range and negative steps" do
# end with zero index
@array.send(@method, eval("(..0).step(-1)")).should == [5, 4, 3, 2, 1, 0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this, my version gave the same answer. And I agree it doesn't look reasonable (going from the -infinity to 0, in steps of -1, you should never arrive here).

it "has inverted closed range and negative steps" do
# start and end with positive index
@array.send(@method, eval("(3..1).step(-1)")).should == [3, 2, 1]
@array.send(@method, eval("(3...1).step(-1)")).should == [2, 1]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mine was

$ ./ruby --disable-gems -e "p [0, 1, 2, 3, 4, 5][(3...1).step(-1)]"
[3, 2]

@array.send(@method, eval("(...-2).step(-2)")).should == [5]

@array.send(@method, eval("(..-2).step(-10)")).should == [4]
@array.send(@method, eval("(...-2).step(-10)")).should == [4]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, all of those should give just [], it seems 🤷

@array.send(@method, eval("(-2...-4).step(-2)")).should == [3]

@array.send(@method, eval("(-2..-4).step(-10)")).should == [2]
@array.send(@method, eval("(-2...-4).step(-10)")).should == [2]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, if I understand/remember the reasoning correctly, with a mix of negative and positive indexes the logic is "convert all indexes to positive (e.g. -1 to ary.length - 1), then iterate between them"

@lxxxvi lxxxvi force-pushed the array-can-be-sliced-with-arithmeticsequence branch from 8b7fe61 to d23057d Compare October 8, 2021 14:47
@lxxxvi
Copy link
Contributor Author

lxxxvi commented Oct 8, 2021

@eregon

https://bugs.ruby-lang.org/issues/18247

I'll cleanup this branch, and copy the weird ones to a new branch on the weekend. 👍

@lxxxvi lxxxvi force-pushed the array-can-be-sliced-with-arithmeticsequence branch from d23057d to a3b33a8 Compare October 9, 2021 14:33
@lxxxvi lxxxvi changed the title WIP: add spec for Array can be sliced with Enumerator::ArithmeticSequence add spec for Array can be sliced with Enumerator::ArithmeticSequence Oct 9, 2021
@lxxxvi
Copy link
Contributor Author

lxxxvi commented Oct 9, 2021

Hi @eregon

As you suggested, I moved the specs that were marked with ??? to another branch and removed them from this branch.

Letme know if you want any more changes, thank you!

Copy link
Member

@eregon eregon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the great work on these specs!

@eregon eregon merged commit 17dbdfc into ruby:master Oct 11, 2021
@lxxxvi
Copy link
Contributor Author

lxxxvi commented Oct 11, 2021

@eregon Thank you for your inputs and support!

@lxxxvi lxxxvi deleted the array-can-be-sliced-with-arithmeticsequence branch January 12, 2023 12:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants