What would you guys think about adding the Thrush combinator toObject?

Discussion in 'Ruby' started by Brian Maddy, Jun 3, 2011.

  1. Brian Maddy

    Brian Maddy Guest

    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))
     
    Brian Maddy, Jun 3, 2011
    #1
    1. Advertisements

  2. 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
     
    Robert Klemme, Jun 3, 2011
    #2
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.