As Rubyists, we write map blocks all the time. These blocks tend to pick up logic that belongs elsewhere. Consider this innocent looking piece of code.
The body of the block is code that is going to be applied to each item. What if instead, Item owned that logic? This gives Item a richer set of domain operations and keeps related item-related logic in one place.
Now we’ve named this domain operation and it has a single source of truth. Our calling code is higher-level and isn’t so tightly coupled to Item internals. As a nice bonus in this case, we get to use symbol to proc syntax.
What about situations where a block has more complicated logic and maybe interacts with other objects? Odds are that most of the logic in there probably still wants to live on Item. After all, the whole point of a map block is applying logic to each of the individual values in the array. If you’re applying logic to an object, that object probably wants to own that behavior.
This is still incredibly item-centric. See how many times the item variable is repeated! But the block also introduces a coupon. That’s OK. An item probably wants to own the logic for calculating its total cost, including applying a coupon. We can move that logic to a method on Item and pass the coupon in as an argument.