Skip to content

User collection proxy fixes #7

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

Merged
merged 7 commits into from
Mar 4, 2013
Merged

User collection proxy fixes #7

merged 7 commits into from
Mar 4, 2013

Conversation

timcraft
Copy link
Contributor

Comment fixes should be self-explanatory.

Including the Enumerable module saves having to define map on your own objects, it also gives you other wonders like inject/each_with_object etc.

I've run the specs locally with ruby 1.9.3, i'll leave the rest to travis.

Cheers,
Tim

@timcraft
Copy link
Contributor Author

Probably also worth moving the count method up onto the User class so that it doesn't clash with the count method defined by Enumerable.

@darragh
Copy link
Member

darragh commented Nov 30, 2012

Awesome - thanks so much. I improved the test around #count a little too here #8 - If the test is valid then it seems it's not clashing with Enumerable. What you think?

@timcraft
Copy link
Contributor Author

@darragh Definitely an improvement, but doesn't fix the clash.

What I mean by clash is that Enumerable#count defines additional "modes" of behaviour (e.g. it takes an optional argument and an optional block), so callers may expect those semantics to be preserved. UserCollectionProxy#count will shadow Enumerable#count, so you won't see anything break in the specs, because they aren't testing the full behaviour of Enumerable#count.

Re-implementing that behaviour is a lot of work for little benefit, so easier to move the UserCollectionProxy#count method elsewhere so it doesn't shadow Enumerable#count.

It seems unlikely to us right now that anyone would want to use Enumerable#count with a block/argument on the collection, but that's the point, you never know. Potential for subtle bugs to crop up in the future elsewhere.

@darragh
Copy link
Member

darragh commented Nov 30, 2012

Cool. What do you think about this approach?

f177830

To explicitly raise an error?

Also - does it matter if I move the include Enumerable to the top?

@timcraft
Copy link
Contributor Author

No difference if you put the include at the top. Including a module adds it to the module inheritance/ancestor chain/hierarchy, it doesn't actually define any methods on the class that includes it. Raising an error is the same problem as not handling the block at all, it's redefining the signature/semantics of the existing method.

Are there any problems with moving the method to Intercom::User.count other than backwards compatibility?

@darragh
Copy link
Member

darragh commented Nov 30, 2012

Yeah - I guess it's just backwards compatibility to move it to Intercom::User.count

So is the problem with count that people will see Intercom::User.all includes Enumerable but get confused as to why it doesn't fully support the Enumerable interface wrt #count? Or are there also subtle problems it will introduce?

@timcraft
Copy link
Contributor Author

Yep exactly. This came about because I tried calling Intercom::User.all.each_with_object, expecting the collection to have included Enumerable. I can imagine a similar wtf moment happening eventually when someone tries to use count with an argument/block.

We could remove UserCollectionProxy#count and let Enumerable#count return the same result, but then it would be making more network calls than necessary when the collection has more than one page. So by introducing Enumerable the UserCollectionProxy#count method essentially becomes an optimisation for the common case.

@timcraft
Copy link
Contributor Author

timcraft commented Mar 4, 2013

@darragh I've implemented what I was trying to describe in 557021b and 9cccbed. It's backwards compatible from an API point of view, but not from a network optimisation point of view. So this will still work, it'll just be inefficient:

Intercom::User.all.count

Easy to fix by changing to this:

Intercom::User.count

Thoughts?

@@ -82,6 +80,14 @@ def self.all
UserCollectionProxy.new
end

# Fetches a count of all Users tracked on Intercom.
#
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An example here would be good for consistency:
e.g.

  # Examples:
  #   Intercom::User.all.count
  #     > 5346

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 0353ffd

@darragh
Copy link
Member

darragh commented Mar 4, 2013

So perhaps something like:

def count(item=nil)
  return super(item) unless item.nil? 
  return super(item) if block_given?
  Intercom::User.count
end

I'm not sure if people do rely on all.count - but if they do, it'd be a really bad regression to start loading all users to get that number. I think we can honour the enumerable api and achieve that.

Thanks for following up on this again, and sorry I let it languish.

@timcraft
Copy link
Contributor Author

timcraft commented Mar 4, 2013

@darragh Personally I would choose the performance hit because I don't think it's good practice to redefine Enumerable methods, but if you want to maintain the existing behaviour I can't think of an alternative.

Implemented in 2ca5cc5, as per your suggestion. Tagged as :nodoc: because I think it's better to emphasize the use of the new Intercom::User.count method. Can then potentially deprecate/remove the optimised Intercom::UserCollectionProxy#count in a major version bump.

@darragh
Copy link
Member

darragh commented Mar 4, 2013

Good idea with :nodoc:, and removing at some later point. Looks great now. Merging!

darragh added a commit that referenced this pull request Mar 4, 2013
@darragh darragh merged commit de90c3f into intercom:master Mar 4, 2013
@timcraft
Copy link
Contributor Author

timcraft commented Mar 4, 2013

@darragh Excellent, thanks!

@darragh
Copy link
Member

darragh commented Mar 4, 2013

Published new version to rubygems.org: https://rubygems.org/gems/intercom

Thanks again for this great improvement.

On Mon, Mar 4, 2013 at 4:37 PM, Tim Craft notifications@github.com wrote:

@darragh https://github.com/darragh Excellent, thanks!


Reply to this email directly or view it on GitHubhttps://github.com//pull/7#issuecomment-14390128
.

murtron pushed a commit that referenced this pull request Jan 29, 2020
…ct-to-passing-id-for-sdk

Conorkeating/migrate passing object to passing id for sdk
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants