-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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 Iterator#slice_after
#7146
Add Iterator#slice_after
#7146
Conversation
Note that this PR is complete by itself. I will add the other methods |
I don't understand why it's called |
@bew After it finds the value it "slices" the enumerable. Or put another way, it slices the enumerable after each time returns a truthy value. |
Ooh ok I get it, is it possible to add an explanation like this in the doc? I think it'd help memorize the naming logic (and probably help with the other iterator you're planning to add) |
An spec for why the reuse is not |
Yes, I thought about putting a restriction to |
e9c4d8b
to
4d1d52d
Compare
Updated:
|
Also added a small explanation to why it's called |
src/iterator.cr
Outdated
include Iterator(Array(T)) | ||
|
||
def initialize(@iterator : I, @block : T -> B, reuse) | ||
@values = [] of T |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if reuse
is an Array
, it'll still create an empty array here for nothing :(
I think you can remove this line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! Fixed! That's the code I originally had before adding all the reuse
logic. Thank you!
4d1d52d
to
58ff560
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
@asterite I liked the no restriction actually. I thought it was intentional to allow more flexibility: For example use an |
For the record: removing the restriction is not possible (or not worth the effort). |
|
||
if reuse | ||
if reuse.is_a?(Array) | ||
@values = reuse |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't @clear_on_next = true
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... you are supposed to pass an empty array as a reuse value. It's not documented what happens if you pass an array that has some values already, but in this case they will be part of the first chunk. Maybe that's good. I wouldn't worry about this now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The obvious usecase for passing an array as reuse
is when you've just used the array from another iterator, meaning the array might not be empty. I don't think it's good to pass the burden of calling clear onto the caller, since it's easy to forget. Also, clear
on an already-empty array is very cheap, so why not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if you want to get chunks but want the first chunk to have some elements beforehand? If the iterator calls clear
there's no way you can do that.
I think we are just inventing use cases. Whenever I used reuse
I passed a boolean. We can maybe remove the ability to pass an array altogether.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want the first chunk to have extra elements:
- that's pretty inflexible, since you can only do it with the first chunk, not the last
- using a named arg called
reuse:
is not the most clear way to achieve this.
For me, reuse
is for avoiding memory allocations only. That's it's only usecase. Always calling clear makes that usecase easier with very small extra expense.
Part of #7142