From: Chris Hulan Date: 2010-04-15T23:20:07+09:00 Subject: Re: Blocks and local variable creation On Apr 15, 6:17 am, John Lane wrote: > Hello, > > I have a simple method: > > def rights_for_item (rights_hash, item) >    rights_hash.each { |k,v| (rights ||= []) << k if v.include? item } >    rights > end > > This does not work because "rights" is created local to the block on > "rights_hash.each" instead of local to the method itself. This makes the > statement returning the value of "rights" to fail because there is no > method local variable called "rights". > > I can do this instead > > def rights_for_item (rights_hash, item) >    rights = Array.new >    rights_hash.each { |k,v| rights << k if v.include? item } >    rights > end > > The problem is this returns an empty array rather than nil if no matches > are found. So I do this: > > def rights_for_item (rights_hash, item) >    rights = Array.new >    rights_hash.each { |k,v| rights << k if v.include? item } >    rights.empty? ? rights : nil > end > > But I don't think it is good idiomatic ruby code. Is there a better way > to write this type of thing ? > -- > Posted viahttp://www.ruby-forum.com/. Hash has a select method, in 1.8 (at least according to the docs) it will a return an array of key,value pairs, in 1.9 it creates a hash with the selected key,value pairs You can use the keys method to get the key values as an array Rather than have the method return two different types (array or nil) why not accept an empty array as the valid indication of no rights? Cheers