Refining Array#sum monkey-patch using Refinements #27363

Merged
merged 1 commit into from Jan 3, 2017

Projects

None yet

8 participants

@amatsuda
Member
amatsuda commented Dec 14, 2016 edited

Here's an alternative implementation of Array#sum.

Current Array#sum unwantedly exposes our own internal orig_sum method to the outside world.
Ruby 2's probably most unused but useful new feature "Refinements" is provided exactly for this use case to define a perfectly private method that can be accessed only inside this file.

I'd like to ask the core members' opinion about this approach, since AFAIK we've never used Refinements in our code base before.
If you like it, I'd love to rewrite some other monkey-patches to this style.
And I guess #25202 can also be more elegantly solved using this technique.

/cc @jeremy

@amatsuda amatsuda Refining Array#sum monkey-patch using Refinements
Because we don't want to see our ugly orig_sum method outside of this file
571f0f3
@yui-knk
Contributor
yui-knk commented Dec 15, 2016

Looks good to me 👍
I wrote Use original Array#sum to speed up calculating.
A defect of alias :orig_sum :sum is to expose #orig_sum to Rails users.
This commit will solve the problem because only Array#sum can access #orig_sum.

I think Refinements are best tool to solve this problem :)

@kamipo
Member
kamipo commented Dec 19, 2016

How about private :orig_sum?

@yui-knk
Contributor
yui-knk commented Dec 19, 2016

We can call a private method by send :orig_sum, so I prefer to Refinements in this context :)

@kamipo
Member
kamipo commented Dec 19, 2016

I see :)

@sgrif sgrif merged commit a194ec8 into rails:master Jan 3, 2017

2 checks passed

codeclimate no new or fixed issues
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@rafaelfranca
Member

I'm fine with using refinements but can we change our monkey-patches to this styles even that refinements are only in the file context?

@amatsuda amatsuda deleted the amatsuda:refined_array_sum branch Jan 4, 2017
@kares
Contributor
kares commented Jan 6, 2017

a late comment ... why does this need to be hidden that much esp. in an open language such as Ruby?
I understand that it seems like a good fit here but have you considered the impact on alternate rubies?

maybe there's a reason why its the most unused feature (besides doing terrible on JRuby) - just guessing
... in general when a Ruby method (esp. from a library) wasn't working as expected ✂️ worked well:
-> its probably not that easy to do that with refinements? would you guys consider an alternative here?

@rafaelfranca
Member

I understand that it seems like a good fit here but have you considered the impact on alternate rubies?

Officially we only support MRI, JRuby support is still work in progress. But which impacts have refinements on alternate rubies?

@printercu
Contributor
printercu commented Jan 19, 2017 edited

UPD Sorry, misunderstood the original purpose of PR.

@amatsuda @yui-knk Maybe it'll be better to use Array.prepend with new new #sum implementation? Something like this:

  module ActiveSupport::NumericSum
     def sum(init = nil, *, &block) #:nodoc:
       init ||= 0 if !init && first.is_a?(Numeric)
       super
     end
  end
  Array.prepend(ActiveSupport::NumericSum)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment