From: Andy Lowry Date: 2013-07-23T02:37:28+09:00 Subject: tap { break } idiom deserves its own Kernel method? 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? -- Posted via http://www.ruby-forum.com/.