Add Enumerable#without #19157

Merged
merged 1 commit into from Mar 2, 2015

Projects

None yet

7 participants

@todd
Contributor
todd commented Mar 2, 2015

Re: #19082

I mostly took the code @dhh provided in the aforementioned issue and made a minor tweak after reviewing the relevant Ruby source and running some benchmarks - Array#reject is actually slower than Array#-, so I'm conditionally calling - on the enumerable if it's an Array. I can provide some benchmarks if anyone would like to see them. I'd also love for someone more well-versed in Ruby internals to take a look at this if they have the time.

@georgeclaghorn georgeclaghorn and 1 other commented on an outdated diff Mar 2, 2015
activesupport/lib/active_support/core_ext/enumerable.rb
@@ -60,6 +60,19 @@ def many?
def exclude?(object)
!include?(object)
end
+
+ # Returns a copy of the enumerable without the specified elements.
+ #
+ # people = ["David", "Rafael", "Aaron", "Todd"]
+ # people.without "Aaron", "Todd"
+ # => ["David", "Rafael"]
+ def without(*elements)
+ if is_a? Array
+ self - elements
@georgeclaghorn
georgeclaghorn Mar 2, 2015 Contributor

How about overriding this method separately in an Array core extension?

@dhh
dhh Mar 2, 2015 Member

👍 to overwriting in an Array core extension. We do that with other methods like blank? etc.

@dhh
Member
dhh commented Mar 2, 2015

Looking good besides for the type check 👏

@JuanitoFatas JuanitoFatas and 1 other commented on an outdated diff Mar 2, 2015
activesupport/lib/active_support/core_ext/enumerable.rb
@@ -60,6 +60,19 @@ def many?
def exclude?(object)
!include?(object)
end
+
+ # Returns a copy of the enumerable without the specified elements.
+ #
+ # people = ["David", "Rafael", "Aaron", "Todd"]
+ # people.without "Aaron", "Todd"
+ # => ["David", "Rafael"]
@JuanitoFatas
JuanitoFatas Mar 2, 2015 Contributor

Add comment # before =>:

# => ["David", "Rafael"] ?

@todd
todd Mar 2, 2015 Contributor

The other examples in this file use the same style.

@JuanitoFatas
JuanitoFatas Mar 2, 2015 Contributor

👌 Sorry.

@todd
todd Mar 2, 2015 Contributor

No worries! Happy to change this to be more consistent with preferred style in another PR 😉

@todd todd and 1 other commented on an outdated diff Mar 2, 2015
...support/lib/active_support/core_ext/array/grouping.rb
@@ -113,4 +113,8 @@ def split(value = nil)
results
end
end
+
+ def without(*elements) # :nodoc:
@todd
todd Mar 2, 2015 Contributor

Should we keep this as nodoc or add separate documentation for this from what's in enumerable.rb?

@dhh
dhh Mar 2, 2015 Member

I’d doc it and say what it does exactly as well as point to the enumerable version with a “this is an optimization of that”.

On Mar 1, 2015, at 18:18, Todd Bealmear notifications@github.com wrote:

In activesupport/lib/active_support/core_ext/array/grouping.rb:

@@ -113,4 +113,8 @@ def split(value = nil)
results
end
end
+

  • def without(*elements) # :nodoc:

Should we keep this as nodoc or add separate documentation for this from what's in enumerable.rb?


Reply to this email directly or view it on GitHub.

@todd
todd Mar 2, 2015 Contributor

Done.

@dhh dhh and 1 other commented on an outdated diff Mar 2, 2015
...support/lib/active_support/core_ext/array/grouping.rb
@@ -113,4 +113,15 @@ def split(value = nil)
results
end
end
+
+ # Returns a copy of the Array without the specified elements.
+ #
+ # people = ["David", "Rafael", "Aaron", "Todd"]
+ # people.without "Aaron", "Todd"
+ # => ["David", "Rafael"]
+ #
+ # Note: This is an optimization of `Enumerable#without`.
@dhh
dhh Mar 2, 2015 Member

Note: This is an optimization ofEnumerable#withoutthat uses Array#- instead of Enumerable#reject for performance reasons.

@todd
todd Mar 2, 2015 Contributor

Done - I changed Enumerable#reject to Array#reject since Array has its own implementation.

@dhh
Member
dhh commented Mar 2, 2015

Great work on this 👍

@dhh dhh merged commit fc91616 into rails:master Mar 2, 2015
@dhh
Member
dhh commented Mar 2, 2015

Failing the build: https://travis-ci.org/rails/rails/jobs/52689785#L1077

We need to require what adds #in?.

@JuanitoFatas
Contributor

@dhh Added in #19161.

@egilburg
Contributor
egilburg commented Mar 2, 2015

@JuanitoFatas the dependency require should be in code and not in test, otherwise the test doesn't test actual scenario with someone only including that specific file, which would break for them.

But given that this is low-level helper method, better to avoid another layer of abstraction and just check elements.include?(element).

@dhh
Member
dhh commented Mar 2, 2015

Wups. I should have caught that. What @egilburg said.

@dhh
Member
dhh commented Mar 2, 2015

Even better 👍

On Mar 1, 2015, at 19:21, Eugene Gilburg notifications@github.com wrote:

@JuanitoFatas the dependency require should be in code and not in test, otherwise the test doesn't test actual scenario with someone only including that specific file.

But given that this is low-level helper method, better to avoid another layer of abstraction and just check elements.include?(element).


Reply to this email directly or view it on GitHub.

@JuanitoFatas
Contributor

@egilburg @dhh Sorry let me fix that.

@todd
Contributor
todd commented Mar 2, 2015

Huh - didn't run across that in my own testing. Sorry about that. I like @egilburg's solution as well.

@todd todd deleted the unknown repository branch Mar 2, 2015
@matthewd
Member
matthewd commented Mar 2, 2015

grouping.rb?

@todd
Contributor
todd commented Mar 2, 2015

Seemed like the most appropriate place to put the new method given the presence of #split in the same file. Is there a better location you can think of?

@dhh dhh added a commit that referenced this pull request Mar 2, 2015
@dhh dhh Move Array#without from Grouping to Access concern and add dedicated …
…test (relates to #19157)
5213183
@dhh
Member
dhh commented Mar 2, 2015

@matthewd Agree, moved it to Access. No worries, @todd it wasn't immediately clear where it should go. But I think it belongs between in access.

@todd
Contributor
todd commented Mar 2, 2015

👍

@tenderlove tenderlove added a commit that referenced this pull request Mar 5, 2015
@tenderlove tenderlove Merge branch 'master' into url_context
* master: (63 commits)
  Revert "delete unused method"
  Revert "mutate the transaction object to reflect state"
  be optimistic about missing route keys
  use arg size for parallel iteration
  ask the routes objects for its Rack env key
  delete unused method
  mutate the transaction object to reflect state
  ask the txn for it's state, not a state object
  change if! to unless
  Remove unneeded comment. [ci skip]
  Move Array#without from Grouping to Access concern and add dedicated test (relates to #19157)
  tests, favor `drop_table` and `:if_exists` over raw SQL.
  Skip the failing tests on Rubinius for now
  Remove not needed .tap
  Wrap inline rescue with or-equal calls
  [ci skip] Fix a typo for PostgreSQL text limit, GB instead of Gb.
  Avoid Ruby versions check on Rubinius
  Make private methods private
  Remove !has_transactional_callbacks? check
  Test against the mail gem's edge
  ...

Conflicts:
	actionpack/lib/action_dispatch/http/url.rb
	actionpack/lib/action_dispatch/routing/route_set.rb
d91aaef
@aripollak
Contributor

Has there been any talk about moving this to except to mirror Hash#except, since the behavior should already be the same for Hashes?

@dhh
Member
dhh commented Mar 9, 2015

That's a good thought, but I don't think it reads as naturally: @people.without(Current.creator) reads better to me than @people.except(Current.creator). If anything, maybe it's a pointer that Hash#except should have a #without alias when that's the more natural flow.

@aripollak
Contributor

I think they both read fine 😁

@dhh
Member
dhh commented Mar 9, 2015

We’re not going for “fine” here ;). It’s a comparative study and to me there’s no contest: The code reads much clearer with #without.

On Mar 9, 2015, at 15:13, Ari Pollak notifications@github.com wrote:

I think they both read fine


Reply to this email directly or view it on GitHub.

@brainopia brainopia added a commit to brainopia/rails that referenced this pull request Mar 25, 2015
@dhh @brainopia dhh + brainopia Move Array#without from Grouping to Access concern and add dedicated …
…test (relates to #19157)
08faf3a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment