Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

add improved version of Enumerable#include?

#6321

Sometimes you want to ask a question like

"Is x 1 or 2?"

Normally, you write this as:

[1,2].include?(x)

which seems backwards to me.

The attached patch to active allows you to instead write:

x.in?(1,2)

I use this all over my code, and thought others might like it.

You can also use in? with an array like so:

x.in?(*my_array)

Other possible names are: one_of?, within?. Any ideas or feedback would be appreciated.

I've attached a patch.

Reported by rubyduo (at gmail) · January 21st, 2011 @ 02:57 PM

State: committed
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Brian Morearty
    Brian Morearty

    I like this extension a lot and am enthusiastically in favor of incorporating this behavior into ActiveSupport, but would suggest one small syntax change.

    I am the the author of the in_enumerable gem which does exactly this. The small difference is that in? takes a single parameter, not a list of *args parameters. Thanks to duck typing, this would allow it to work with any type that implements include?:

       # Array
       a = [1,2,3]
       3.in?(a)             # => true
       4.in?(a)             # => false
    
       # Hash
       h = { "a" => 100, "b" => 200 }
       "a".in?(h)           # => true
       "z".in?(h)           # => false
    
       # String
       "lo".in?("hello")    # => true
       "ol".in?("hello")    # => false
       ?h.in?("hello")      # => true
    
       # Range
       25.in?(1..50)        # => true
       75.in?(1..50)        # => false
    
       # Set
       require 'set'
       s = Set.new([1,2])
       1.in?(s)             # => true
       3.in?(s)             # => false
    
       # Even Module
       module A
       end
       class B
         include A
       end
       class C < B
       end
       A.in?(B)             # => true
       A.in?(C)             # => true
       A.in?(A)             # => false
    

    I have attached an alternate patch that implements in? in this way.

    Although in_enumerable does not have not_in?, I think it's nice idea because it cleans up the 'not' syntax a bit so I've included it in my alternate patch.

    I agree with your initial suggested name: in? seems to me the most obvious choice. In fact early versions of Ruby apparently had an Object#in? method. See the side note at the end of my blog post about in_enumerable: http://ilikestuffblog.com/2009/12/24/now-you-can-use-obj-inarray-in...

    I would be happy to deprecate the in_enumerable gem if this gets put into ActiveSupport.

    January 21st, 2011 @ 06:07 PM

  2. Brian Morearty
    Brian Morearty

    P.S. In a completely bizarre coincidence of timing, just this morning I thought to myself "I really ought to submit a patch to add in_enumerable's behavior to ActiveSupport." So I logged in to Lighthouse and saw rubyduo's suggestion for the exact same behavior, right at the top of the list of tickets.

    January 21st, 2011 @ 06:11 PM

  3. rubyduo (at gmail)
    rubyduo (at gmail)

    I like your change, since now you can write x.in?(1..50)

    On the other hand, it is nice to just type x.in?(1,2) instead of the wordy x.in?([1,2]).

    We could get the best of both worlds, by handling single and multiple arguments slightly differently, like so:

    def in?(*args)
      container = (args.size == 1 && args.responds_to(:include?)) ? args[0] : args
      container.include?(self)
    end
    

    I'm on the fence on this one.

    January 21st, 2011 @ 07:52 PM

  4. Brian Morearty
    Brian Morearty

    Thanks, rubyduo. I also thought about combining them to get the best of both worlds. The problem is it will lead to ambiguous cases:

    names = ["Brian"]
    "B".in?(*names)   # => true
    
    names = ["Brian","rubyduo"]
    "B".in?(*names)   # => false
    

    So the function would be hard to use if it returns different values depending on the length of the array passed in.

    For that reason I think in this case overloading the arguments would lead to hard-to-track-down bugs.

    January 21st, 2011 @ 09:29 PM

  5. rubyduo (at gmail)
    rubyduo (at gmail)

    You're right about the ambiguity. I'm now on your side of the fence. It'd sure be nice to see your patch (object_in_with_duck_typing.diff) applied to ActiveSupport.

    January 21st, 2011 @ 10:42 PM

  6. Brian Morearty
  7. Rohit Arondekar
    Rohit Arondekar
    • Importance changed from to Low

    Brian, could you post your patch suggestion to the core mailing list? http://groups.google.com/group/rubyonrails-core To try and gather some support for this patch. Otherwise it's most likely that it will remain buried in Lighthouse for a long time.

    January 26th, 2011 @ 10:08 AM

  8. Brian Morearty
    Brian Morearty

    Rohit, thanks for the quick lesson in how to garner support for a Rails core patch. I've followed your suggestion. The post is here:

    http://groups.google.com/group/rubyonrails-core/browse_thread/threa...

    January 26th, 2011 @ 05:34 PM

  9. peter_v
  10. rails
    rails
    • State changed from new to open

    This issue has been automatically marked as stale because it has not been commented on for at least three months.

    The resources of the Rails core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.

    Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.

    April 27th, 2011 @ 01:00 AM

  11. rails
    rails
    • State changed from open to stale

    April 27th, 2011 @ 01:00 AM

  12. Prem Sichanugrist (sikachu)
    Prem Sichanugrist (sikachu)
    • State changed from stale to committed

    Actually, this ticket should be marked as committed. I forgot >_<

    This ticket related to this pull request: https://github.com/rails/rails/pull/258

    April 27th, 2011 @ 09:56 AM