0

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'
Augustin Riedinger
  • 20,909
  • 29
  • 133
  • 206

2 Answers2

1

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]
Stefan
  • 109,145
  • 14
  • 143
  • 218
  • The [tap](http://ruby-doc.org/core-2.1.3/Object.html#method-i-tap) `Object` method almost does that... – Augustin Riedinger Oct 15 '14 at 09:37
  • And this post refers to it too: http://stackoverflow.com/questions/26378890/ruby-reuse-value-in-a-block-without-assigning-it-to-variable-write-object-meth – Augustin Riedinger Oct 15 '14 at 09:43
  • 2
    Is it me or you've just posted your own question as a reference in the comment of the answer of your question referring to your question again which is mentioned by you in your comment as a reference to your own question and so on..? – Surya Oct 15 '14 at 09:46
  • Ok I realize now the mistake. :) I wanted to say that the question is related to this one: http://stackoverflow.com/questions/7878687/combinatory-method-like-tap-but-able-to-return-a-different-value/7879071#7879071 – Augustin Riedinger Oct 15 '14 at 10:53
  • @AugustinRiedinger not really, tap returns the object, not the result of the block. – Bernhard May 05 '17 at 11:54
  • Object#yield_self was added in Ruby 2.5. It does exactly what decompose does when you give it a block, and as a bonus, it gives you an Enumerator over the object you call it on if you don't pass a block. – Jenner La Fave Oct 25 '18 at 00:35
0

It actually exists (I could not believe it didn't).

It is called BasicObject#instance_eval. Here's the doc: http://apidock.com/ruby/BasicObject/instance_eval

Available since Ruby 1.9 as this post explains: What's the difference between Object and BasicObject in Ruby?

Community
  • 1
  • 1
Augustin Riedinger
  • 20,909
  • 29
  • 133
  • 206