From: sto.mar@... Date: 2013-07-23T05:48:51+09:00 Subject: Re: tap { break } idiom deserves its own Kernel method? 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 --