[ruby-core:115648] [Ruby master Feature#20049] Destructive drop_while for Array and Hash

Issue #20049 has been reported by chucke (Tiago Cardoso). ---------------------------------------- Feature #20049: Destructive drop_while for Array and Hash https://bugs.ruby-lang.org/issues/20049 * Author: chucke (Tiago Cardoso) * Status: Open * Priority: Normal ---------------------------------------- I propose a "drop_while!" variant for arrays and hashes, which changes the current instance. ```ruby h = {foo: 0, bar: 1, baz: 2} h.drop_while!{|element| key, value = *element; value < 2 } h #=> # => { baz: 2 } ``` -- https://bugs.ruby-lang.org/

Issue #20049 has been updated by matheusrich (Matheus Richard). What would be the return value? The same as `drop_while`? ---------------------------------------- Feature #20049: Destructive drop_while for Array and Hash https://bugs.ruby-lang.org/issues/20049#change-105598 * Author: chucke (Tiago Cardoso) * Status: Open * Priority: Normal ---------------------------------------- I propose a "drop_while!" variant for arrays and hashes, which changes the current instance. ```ruby h = {foo: 0, bar: 1, baz: 2} h.drop_while!{|element| key, value = *element; value < 2 } h #=> # => { baz: 2 } ``` -- https://bugs.ruby-lang.org/

Issue #20049 has been updated by chucke (Tiago Cardoso). I'd say it returns self, or nil if no changes were made, just like other ! Methods of the kind. ---------------------------------------- Feature #20049: Destructive drop_while for Array and Hash https://bugs.ruby-lang.org/issues/20049#change-105602 * Author: chucke (Tiago Cardoso) * Status: Open * Priority: Normal ---------------------------------------- I propose a "drop_while!" variant for arrays and hashes, which changes the current instance. ```ruby h = {foo: 0, bar: 1, baz: 2} h.drop_while!{|element| key, value = *element; value < 2 } h #=> # => { baz: 2 } ``` -- https://bugs.ruby-lang.org/

Issue #20049 has been updated by chucke (Tiago Cardoso). Started a PR in github: https://github.com/ruby/ruby/pull/9193 ---------------------------------------- Feature #20049: Destructive drop_while for Array and Hash https://bugs.ruby-lang.org/issues/20049#change-105646 * Author: chucke (Tiago Cardoso) * Status: Open * Priority: Normal ---------------------------------------- I propose a "drop_while!" variant for arrays and hashes, which changes the current instance. ```ruby h = {foo: 0, bar: 1, baz: 2} h.drop_while!{|element| key, value = *element; value < 2 } h #=> # => { baz: 2 } ``` -- https://bugs.ruby-lang.org/

Issue #20049 has been updated by matz (Yukihiro Matsumoto). Status changed from Open to Feedback I reject `Hash#drop_while!` because the order is not (and should not be) important for Hash and the order of hash is fragile anyway. Whereas `Array#drop_while!` has chance. Could you explain the use-case for the new method, please? Matz. ---------------------------------------- Feature #20049: Destructive drop_while for Array and Hash https://bugs.ruby-lang.org/issues/20049#change-105758 * Author: chucke (Tiago Cardoso) * Status: Feedback * Priority: Normal ---------------------------------------- I propose a "drop_while!" variant for arrays and hashes, which changes the current instance. ```ruby h = {foo: 0, bar: 1, baz: 2} h.drop_while!{|element| key, value = *element; value < 2 } h #=> # => { baz: 2 } ``` -- https://bugs.ruby-lang.org/

Issue #20049 has been updated by zverok (Victor Shepelev).
Could you explain the use-case for the new method, please?
Not the original author, but I think one of the frequent use cases is some parser- or scanner-alike code. E.g., after reading some "dirty" data, ```ruby lines.drop_while! { ln.match?(/HEADER:/) } # operate with clean `lines` here ``` (I had more generic take on this in my ticket about "consuming" enumerators #19061, which I haven't had time to pursue the better proposal/explanation this year, but want to return during the next one.) ---------------------------------------- Feature #20049: Destructive drop_while for Array and Hash https://bugs.ruby-lang.org/issues/20049#change-105764 * Author: chucke (Tiago Cardoso) * Status: Feedback * Priority: Normal ---------------------------------------- I propose a "drop_while!" variant for arrays and hashes, which changes the current instance. ```ruby h = {foo: 0, bar: 1, baz: 2} h.drop_while!{|element| key, value = *element; value < 2 } h #=> # => { baz: 2 } ``` -- https://bugs.ruby-lang.org/

Issue #20049 has been updated by chucke (Tiago Cardoso). thx for the response matz! The specific use case can be found here: https://gitlab.com/os85/http-2-next/-/blob/master/lib/http/2/next/connection... The HTTP/2 allows frames to be ackowledged for streams that have been closed "recently", which in this case means "last 15 seconds". functionally, I'm using an hash to store them, with insertion at the time they're closed, and in a given event, I proceed to clean up the ones that have timed-out. the first implementation traversed the whole collection for all timed out streams, and removed them. This O(n) complexity surfaced as a bottleneck in some benchmarks around long-lived connections. In order to improve it, I use #drop_while , as I know that, due to the hash preserving insertion order, I know that possibly timed out streams are left-most, so I can stop processing the collection as soon as I find a non-timed out element. This greatly improved benchmarks, but the resulting multiple objects generated by the successive Enumerable#drop_while + #to_h calls resulted in a (smaller) bottleneck that could be greatly reduced by reusing the same object. can you clarify what you mean by "the order of hash is fragile anyway"? As I understood, there are other stdlib data structures relying on hash order insertion. Are there plans to remove this guarantee? I guess I could rely on Array#drop_while!, although that'd hurt lookups. ---------------------------------------- Feature #20049: Destructive drop_while for Array and Hash https://bugs.ruby-lang.org/issues/20049#change-105773 * Author: chucke (Tiago Cardoso) * Status: Feedback * Priority: Normal ---------------------------------------- I propose a "drop_while!" variant for arrays and hashes, which changes the current instance. ```ruby h = {foo: 0, bar: 1, baz: 2} h.drop_while!{|element| key, value = *element; value < 2 } h #=> # => { baz: 2 } ``` -- https://bugs.ruby-lang.org/

Issue #20049 has been updated by chucke (Tiago Cardoso). for comparison, the original implementation can be found here: https://github.com/igrigorik/http-2/blob/master/lib/http/2/connection.rb#L70... (http-2-next is a fork of http-2 gem). FWIW zverok's use case is also reasonably common. ---------------------------------------- Feature #20049: Destructive drop_while for Array and Hash https://bugs.ruby-lang.org/issues/20049#change-105774 * Author: chucke (Tiago Cardoso) * Status: Feedback * Priority: Normal ---------------------------------------- I propose a "drop_while!" variant for arrays and hashes, which changes the current instance. ```ruby h = {foo: 0, bar: 1, baz: 2} h.drop_while!{|element| key, value = *element; value < 2 } h #=> # => { baz: 2 } ``` -- https://bugs.ruby-lang.org/
participants (4)
-
chucke (Tiago Cardoso)
-
matheusrich (Matheus Richard)
-
matz (Yukihiro Matsumoto)
-
zverok (Victor Shepelev)