# block returns and hash element returns

Discussion in 'Ruby' started by Trans, Nov 6, 2005.

1. ### TransGuest

A question and a thought (or two).

Is there a way to return from a block without returning from the whole
method? Eg.

# This behavior
def double_collect( array )
array.collect { |v| v*2 }
end

# Nope, returns from double_collect
def double_collect( array )
array.collect { |v| return v*2 }
end

# Nope, returns only first iteration
def double_collect( array )
array.collect { |v| break v*2 }
end

Would something like #local_return be useful?

The reason I ask is b/c I was also thinking about a possbile special
form of 'return' that can handle hash assocations:

def double_collect( array )
array.collect { |v| local_return v => v*2 }
end
double_collect( [1,2,3] ) #=> { 1=>2, 2=>4, 3=>6 }

Presently I use a facet called #graph to do this:

array.graph { |v| [v, v*2] }

But returning that array just feels wrong (not to mention inefficient).

Thanks,
T.

Trans, Nov 6, 2005

2. ### Guest

On Nov 6, 2005, at 1:07 AM, Trans wrote:
> A question and a thought (or two).
>
> Is there a way to return from a block without returning from the whole
> method?

I think you are looking for 'next'

irb(main):001:0> [1,2,3,4].each { |x| next if x%2==0; puts "#{x} is
odd" }
1 is odd
3 is odd
=> [1, 2, 3, 4]

Gary Wright

, Nov 6, 2005

3. ### TransGuest

#next, of course! Thank you.

Okay, so use #next in place of #local_return.

h1 = { :a => 1, :b => 2, :c => 3 }
h2 = h1.collect { |k,v| next k => v*2 }
h2 => { :a => 2, :b => 4, :c => 6 }

Could do this by modifying collect to merge hashes if they are the
yield result, but that's not exactly the same. since it would make it
impossible to collect hashes, and it would have not advantage over the
#graph method either --just substituting a hash for the array.

T.

Trans, Nov 6, 2005