Ryan Leavengood wrote:

> But you are cheating here by leaving out the "setup code" that allows
> you to call ObjectSpace.select.

I don't really see that as cheating since the code is already written
and stored in a reusable lib. EnumerableArgs is not something you'd use
on an existing classes in general, but on something you've created new
--otherwise you'd be redefining #each in a core/standard lib which is
not something you want to do lightly in the first place. It doesn't
really bother ObjectSpace b/c it has no #each method or Enumerable
inclusion, but has an each-like method. So it makes a good example
case.

> I would be curious to see other
> examples where you use EnumerableArgs, because as Robert says there
> aren't many "each" methods that take a parameter. Using ri on my 1.8.2
> install, I could only find String#each and IO#each, both of which take
> an optional "separator" parameter.

And those are poor parameters to beign with --they have bad side effect
b/c they default to a global var. Not a very robust solution. I hope
Matz will be changing that for 2.0.

> I personally don't see many cases
> where I would need to override the default, especially when calling
> Enumerable methods. Plus since both already include Enumerable, I'm
> not sure what kinds of wacky things would happen if you mixed in
> EnumerableArgs as well.

If you did include EnumerableArgs there would be no adverse effects
--assumming I it's working as it was designed to. The design goal was
complete transparency. Of course nothing's perfect. I originally wrote
the code for 1.6 so some things have changed. But I did just spend a
couple hours rewritting it to use Enumerator and dynamically generate
the methods based on Enumerable. That way I no longer need to keep it
up-to-date by hand. (Seems a tad slower though suprisingly) So it
should work nearly flawslessly. There are only two caveats. 1) #inject
and #zip can not pass parameters to #each due to their negative arity,
so they work just as they do in Enumerable. And 2) #find (alias
#detect) has been modified to get rid of the 'ifnone' parameter, and
instead made an optional keyword parameter (:ifnone=>...), which makes
more sense considering what it is and how rare it's usage is (it only
accepts a proc). So only this last caveat would present a compatabilty
issue if you were for some strange reason to try and make it a complete
drop in replacemet for Enumerable.

Now what kind of use real might it have besides ObjectSpace? Simply
imagine any class that might have multipe each methods:

  class House
    include EnumerableArgs

    def each_bedroom ...
    def each_closet ...
    def each_room ...
    def each_hallway ...

    def each(which=:room, &blk)
      send("each_#{which}", &blk)
    end
  end

  h = House.new
  h.select(:bathroom) { |b| ... }

T.