From: Robert Klemme Date: 2011-06-04T00:40:25+09:00 Subject: Re: What would you guys think about adding the Thrush combinator to Object? 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/