On 03.06.2011 15:30, Brian Maddy wrote:
> Hello,
>
> I'd like to get some peoples' opinion on this. I recently needed to
> make a change to an enumerator that changed the number of items in the
> enumerator. I wanted to be able to chain this function in like map and
> inject, but it needed to operate on the enumerator, not just the items
> in it. Adding functions like this to the Object or Enumerator class
> seemed like poor design (since there could be many of them). I was
> surprised to find out that there isn't a Thrush combinator function on
> the Object class. I ended up copying the code Reganwald
> (https://github.com/raganwald/homoiconic/blob/master/2008-10-30/thrush.markdown#readme)
> and wanted to see if anyone else thought it would be a good addition
> to the Ruby language. Here's the code:
>
> class Object
>    def into(expr = nil)
>      expr.nil? ? yield(self) : expr.to_proc.call(self)
>    end
> end
>
> Thoughts?
>
>
> Here's my situation in more detail for those who are interested:
>
> I had some data like this:
>
> orig_data = [{:type =>  :products, :ids =>  [1, 2, 3, 4, 5]}, {:type =>
> :stores, :ids =>  [6, 7, 8, 9]}]
>
> that I needed to split into smaller chunks, like this:
>
> [{:type =>  :products, :ids =>  [1, 2]},
>   {:type =>  :products, :ids =>  [3, 4]},
>   {:type =>  :products, :ids =>  [5]},
>   {:type =>  :stores, :ids =>  [6, 7]},
>   {:type =>  :stores, :ids =>  [8, 9]}]
>
> My function for splitting them was pretty simple, but had to take in
> an enumerator:
>
> def slice_by_ids(hashes)
>    Enumerator.new do |yielder|
>      hashes.each do |hash|
>        hash[:ids].each_slice(2) do |slice|
>          yielder.yield hash.merge(:ids =>  slice)
>        end
>      end
>    end
> end
>
> This function seemed way too specific to put on the Enumerator class,
> but if we had the Thrush combinator we could do something like this:
>
> orig_data.into(&method(:slice_by_ids))
>
> This is also still easily chainable and maintains laziness:
>
> orig_data.
>    lazy_map(&method(:do_stuff)).
>    into(&method(:slice_by_ids)).
>    lazy_map(&method(:do_other_stuff))
>

Hm, that looks quite complex to me.  Why not just do this?

require 'pp'

sliced = []

orig_data.each do |h|
   h[:ids].each_slice 2 do |sl|
     sliced << h.merge(:ids => sl)
   end
end

pp orig_data, sliced

Kind regards

	robert

-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/