Am 22.07.2013 19:37, schrieb Andy Lowry:
> I use this idiom from time to time:
>
>    x = expr.tap{|value| break expr-involving-value)}
>
> It works well, but reading it requires the reader to understand a
> relatively obscure part of ruby, namely the behavior of break during a
> yield.
>
> Here's my most recent case where the idiom useful: I've got a list of
> model object ids, and I want produce an array of the model objects in
> the order their ids appear in that list.
>
> Obviously, this works:
>
>     id_list.map{|id| Model.find(id)}
>
> Here's an approach that does a single query:
>
>     unsorted = Model.where(id: id_list)
>     objs_map = unsorted.reduce(Hash.new) {|h,o| h[o.id] = o; h}
>     sorted = id_list.map{|id| objs_map[id]}
>
> Here's the same thing using tap/break, to make it more obvious that the
> only thing I'm really interested in is that final value "sorted":
>
>     sorted = Model.where(id: id_list).tap do |unsorted|
>       break unsorted.reduce(Hash.new) {|h,o| h[o.id] = o; h}
>     end.tap do |objs_hash|
>       break id_list.map{|id| objs_hash[id]}
>     end
>
> I find enough uses for this idiom that I'm thinking it'd be worth giving
> it a name and its own Kernel method, rather than forcing the use of a
> relatively narrowly understood language feature (behavior of break
> during yield). "pipe" or "transform" may be a good name for it.
> Definition would be almost identical to that of tap.
>
>    Kernel.module_eval do
>      def pipe
>        yield self
>      end
>    end
>
> Then the example above turns into:
>
>    sorted = Model.where(id: id_list).pipe do |unsorted|
>      unsorted.reduce(Hash.new) {|h,o| h[o.id] = o; h}
>    end.pipe do |objs_map|
>      id_list.map{|id| objs_hash[id]}
>    end
>
> Any thoughts?

To me this looks like defining a method for doing method chaining...?!

IMO, `tap' is overused or often even misused anyway, but probably
I only think that because I do not get its many advantages... :)
But what I'm sure of is that the above tap-break idiom is too
cryptic for me.

Regards,
Marcus


-- 
<https://github.com/stomar/>