Ran into a quick "gotcha" with .tap that seems worth sharing in case it trips anyone up. As you mentioned above, the documentation says that .tap: "Yields self to the block, and then returns self." This is important to remember, because sometimes we think we're modifying an object when we actually aren't.
For example, let's say we want to add elements from a new array to an existing array:
# using .concatary=[1,2,3]ary.concat([4,5,6])#> [1, 2, 3, 4, 5, 6]# using +=ary=[1,2,3]ary+=[4,5,6]#> [1, 2, 3, 4, 5, 6]
By all appearances they look like they do the same thing; one might suppose += is simply a "syntactic sugar" shortcut for .concat. Besides, += is quicker to type and easy to conceptualize what you're doing, right? Let's try both approaches with .tap:
ary=[1,2,3]ary.tapdo|a|# do some thingsa.concat([4,5,6])# do more thingsend#> [1, 2, 3, 4, 5, 6]# ...as expectedary=[1,2,3]ary.tapdo|a|# do some thingsa+=[4,5,6]# do more thingsend#> [1, 2, 3]# ...wait, what?
Why the difference? Concat does what we expect because it works by appending the new elements to the existing array. But + (and therefore +=) creates a new array with elements from both originals and returns the new one, which we're just throwing away here because we're not assigning it to anything. That means the original array object we tapped from remains unchanged, and that's what .tap then returns or passes on to the next method in the chain.
In short, if you're expecting the tapped object to be modified within the tap block, make sure you're using methods that will actually modify self instead of returning a modified copy.
Is this really a gotcha of tap though? It doesn't change the behaviour of tap, it still returns self, its just that you used .concat vs += - or did I miss the point?
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Ran into a quick "gotcha" with .tap that seems worth sharing in case it trips anyone up. As you mentioned above, the documentation says that .tap: "Yields self to the block, and then returns self." This is important to remember, because sometimes we think we're modifying an object when we actually aren't.
For example, let's say we want to add elements from a new array to an existing array:
By all appearances they look like they do the same thing; one might suppose += is simply a "syntactic sugar" shortcut for .concat. Besides, += is quicker to type and easy to conceptualize what you're doing, right? Let's try both approaches with .tap:
Why the difference? Concat does what we expect because it works by appending the new elements to the existing array. But + (and therefore +=) creates a new array with elements from both originals and returns the new one, which we're just throwing away here because we're not assigning it to anything. That means the original array object we tapped from remains unchanged, and that's what .tap then returns or passes on to the next method in the chain.
In short, if you're expecting the tapped object to be modified within the tap block, make sure you're using methods that will actually modify self instead of returning a modified copy.
Is this really a gotcha of
tap
though? It doesn't change the behaviour oftap
, it still returns self, its just that you used.concat
vs+=
- or did I miss the point?