From: Christopher Dicely Date: 2011-05-29T04:08:23+09:00 Subject: Re: Problem in using %:whatever in enumumerations On Sat, May 28, 2011 at 7:00 AM, RichardOnRails wrote: > On May 28, 2:20 am, Victor Deryagin wrote: > > Thanks for your response. > >> > greek = %w{Alpha Beta Gamma} >> > puts greek.all? { |s| s.length == 5 }              #  (correct)  => false >> > puts greek.all? { |s| (4..5).include? s.length }   #  (correct)  => true >> > puts greek.all?(&:length)                      #  (programmer error)     => true > >> ... If that's not what you want (e.g. you need { |s| s.length == 5 }) - >> construct block yourself. > > I did construct the block myself in the first couple of examples > (lines 2 & 3) but was searching (in line 4) for another way of > expressing the requirement. > > I finally found a way to use a lambda in the following statements in > place of line 4: > > lam = lambda { |item, len| item.length == 5 } > puts greek.all? { |s| lam.call(s,5)}                    #  (correct)  => false Note that the second argument to lambda is never used, as you've hardcoded 5 for the length to use for the test rather than using the second argument. If you want something where you can change the length to test for on different calls, replace the first line with: lam = lambda { |item, len| item.length == len } > > Of course, the verbosity of this pair of statements is unsatisfying, > so I'm still searching for succinct alternatives. There isn't anything I can think of built in that's more succinct, but if this kind of test is common in your code, you can abstract part of it out to a library method on Enumerable and make the code more succinct and clear at the point of call. # elsewhere, extend Enumerable # (obvious parallels any_have?, one_has?, count_having, etc. could also be defined) module Enumerable def all_have?(attribute, value) all? { |item| item.__send__(attribute) == value } end end # then, in the point you were working on greek.all_have? :length, 5