TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Ruby `reject!`

306 pointsby dmitover 8 years ago

12 comments

drodgersover 8 years ago
I love this blog, but I&#x27;m not sure that I agree with this:<p>&gt; In my mind, I’d just rather not have a reject! at all, and callers who need to mutate an array in-place can figure out how to do safely with respect to their own use cases.<p>We ought to have a standard version of the reject! code precisely <i>because</i> it&#x27;s so difficult to get right. Saying application developers should solve the problem themselves just sounds like some sort of political move: &#x27;sure they may get the edge cases wrong, but then it will be their fault not ours&#x27;.<p>One of the best things about Ruby is that having helper methods for every kind of possible operation frees application developers from re-solving these edge-case problems and allows them to just write their business logic.
评论 #13692151 未加载
评论 #13691857 未加载
评论 #13691976 未加载
评论 #13693483 未加载
评论 #13692137 未加载
pmarreckover 8 years ago
Shameless plug:<p>After years working with Ruby, I felt that &quot;bang&quot; methods should only be used for methods which mutate the receiver. Many methods which <i>do</i> do so do not have a &quot;!&quot; at the end.<p>To that end I created a little library called &quot;Bang All The Things&quot; :) <a href="https:&#x2F;&#x2F;github.com&#x2F;pmarreck&#x2F;ruby-snippets&#x2F;blob&#x2F;master&#x2F;bang_all_the_things.rb" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;pmarreck&#x2F;ruby-snippets&#x2F;blob&#x2F;master&#x2F;bang_a...</a><p>I&#x27;m convinced that this simplification helps prevent bugs, at the minor cost of changing some conventions possibly borrowed from other languages.<p>I have since (mostly) moved on to Elixir which does not have the &quot;mutability problem&quot; at all.
评论 #13692659 未加载
评论 #13693732 未加载
ouidover 8 years ago
I think that perhaps the most interesting part of this article is that it comes from a blog called &#x27;accidentallyquadratic&#x27; with more than one entry.
评论 #13692321 未加载
评论 #13693011 未加载
评论 #13693149 未加载
评论 #13691713 未加载
ecoover 8 years ago
One of the more confusing parts of the C++ standard library algorithms is remove&#x2F;remove_if. A new user would think calling remove(v.begin(), v.end(), value_to_remove) would result in the value being removed from the container[1]. Instead, they&#x27;ll find that all it did was shift around the ordering of the vector and leave the elements you wanted removed in place at the end (if you read the linked article you can already see where this is going) which is a very unintuitive result. They might look up the function signature and notice it returns an iterator which is also surprising.<p>Even after discovering they have to call the container&#x27;s erase method using the result of remove and an iterator to the end of the container[2] they&#x27;d probably just decide that remove just has a terrible design. It takes experience and some data structures knowledge to realize why it is designed the way it is.<p>The design of remove means every element that remains are only be shifted (in the case of an array&#x2F;vector), at most, one time. The naive approach results in the problem described in the article where you are constantly shifting the elements forward as you progress through the container.<p>The usability of remove is still a problem (the concept shouldn&#x27;t need a wikipedia page explaining it) but the way it was done was done for good reasons (within the design decisions of STL at least). It&#x27;s probably fixed in the C++ ranges proposal but I haven&#x27;t looked.<p>D&#x27;s standard algorithm library remove[3] (which is very much based on Stepanov&#x27;s STL too) goes one performance step further and lets you specify the swap strategy so that if stability isn&#x27;t a requirement the number of shifts required is the absolute minimum possible (essentially moving elements from the end of the range into spots freed up by the items being removed).<p>1. Slightly more experienced users would quickly notice that it can&#x27;t remove the value, it has no reference to the container to change its length.<p>2. So common and unintuitive it gets its own wikipedia page: <a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Erase%E2%80%93remove_idiom" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Erase%E2%80%93remove_idiom</a><p>3. <a href="http:&#x2F;&#x2F;dlang.org&#x2F;phobos&#x2F;std_algorithm_mutation.html#.remove" rel="nofollow">http:&#x2F;&#x2F;dlang.org&#x2F;phobos&#x2F;std_algorithm_mutation.html#.remove</a>
评论 #13696257 未加载
评论 #13694492 未加载
sriharisover 8 years ago
Why is `reject!` even a separate, and different implementation than `select!`? Perf reasons?<p>Haskell&#x27;s Data.List doesn&#x27;t seem to even have a remove&#x2F;reject. Clojure&#x27;s remove is simply a complement of filter.
评论 #13694034 未加载
评论 #13692985 未加载
评论 #13698059 未加载
Dirlewangerover 8 years ago
Avoiding this should be as simple as using the inverse, `select!`, and then flipping whatever the check is in the block, right?
评论 #13693010 未加载
评论 #13692314 未加载
skywhopperover 8 years ago
I can&#x27;t agree with the conclusion. Sure complexity is complex, but the solution here would seem to be better performance analysis of the standard library rather than blindly avoiding risk. How do you know where to stop? All built in block-accepting methods for enumerator types would seem to be equally risky in this analysis.
评论 #13691751 未加载
tzwmover 8 years ago
So what is the right way to do the same thing? Use `select` and get new array included elements we want to keep instead of using `reject!`?
评论 #13692056 未加载
评论 #13692110 未加载
jerianasmithover 8 years ago
Quite a comprehensive Post ! What makes Ruby block an essential feature of language is it&#x27;s power and elegance.
pjfitzgibbonsover 8 years ago
I think worth clarifying, the fix on svn r49255 is in git tag v2_3_1, so if you&#x27;re on ~2.3.1 Then you&#x27;re back to linear #reject.
gkyaover 8 years ago
I find it weird that the case is called a &quot;bug&quot; multiple times. Sure, if its o(n^2), that&#x27;s a problem, but if the code works correctly at the end, it&#x27;s not a bug.
评论 #13691846 未加载
评论 #13691721 未加载
评论 #13691683 未加载
评论 #13692038 未加载
评论 #13692032 未加载
评论 #13694423 未加载
评论 #13692006 未加载
评论 #13692164 未加载
评论 #13691690 未加载
throwaway1579over 8 years ago
Can&#x27;t wait for the entry on quicksort.