Search code examples
rubyenumerator

Ruby: reuse value in a block without assigning it to variable (write object method on the fly)


There are several situations where I'd like to apply a block to a certain value and use the value inside this block, to use the enumerator coding style to every element.

If such method would be called decompose, it would look like:

result = [3, 4, 7, 8].decompose{ |array| array[2] + array[3] } # result = 15

# OR

result = {:key1 => 'value', :key2 => true}.decompose{ |hash| hash[:key1] if hash[:key2] } # result = 'value'

# OR

[min, max] = [3, 4, 7, 8].decompose{ |array| [array.min, array.max] } # [min, max] = [3, 8]

#  OR

result = 100.decompose{ |int| (int - 1) * (int + 1) / (int * int) } # result = 1

# OR

result = 'Paris'.decompose{ |str| str.replace('a', '') + str[0] } # result = 'PrisP'

Solution

  • The method simply yields self to the block, returning the block's result. I don't think it exists, but you can implement it yourself:

    class Object
      def decompose
        yield self
      end
    end
    
    [3, 4, 7, 8].decompose{ |array| array[2] + array[3] }
    #=> 15
    
    {:key1 => 'value', :key2 => true}.decompose{ |hash| hash[:key1] if hash[:key2] }
    #=> "value"
    
    [3, 4, 7, 8].decompose{ |array| [array.min, array.max] }
    #=> [3, 8]