Collection Returns
#32838
Replies: 1 comment 2 replies
-
Hey there 👋, This is a really long post 😅 Didn't read it all but I'll drop this over here in case it can help you. Otherwise, just ignore my message 🙏 When I want to do something like this: $deck = collect(['a', 'b', 'c']);
$shuffled = $deck->shuffle(); I do it like this: $deck = collect(['a', 'b', 'c']);
$shuffled = (clone $deck)->shuffle(); |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
With collection methods there are a few different scenarios for the return value:
A new collection
diff
filter
merge
shuffle
times
The existing collection
add
forget
prepend
push
An element from the existing collection
get
last
pop
pull
Some type of aggregate value
avg
median
mode
This list is not exhaustive.
It is the first 2 groups that I want to focus this discussion on, methods that return a new Collection, and methods that return an existing Collection.
The problem I've run into is both scenarios can be desirable in different situations. Let's explore 2 examples.
Let's say I have a
Cards
collection, which is made up of manyCard
objects. I instantiate it with a deck of 52 cards, which I want to be my source of truth for all the cards that exist in this game.If I want to
shuffle
the cards, I'm now creating a brand new object, and my$deck
is no longer the source of truth for cards that exist in the game. In this scenario, it would be better ifshuffle
acted on and returned the existing Collection.Another oddity is when dealing with
merge
andadd
.merge
will return a new Collection, andadd
will alter and return the existing Collection. So if you want to add multiple item and keep the original object, you actually need to loop overadd
.We'll stick with our card example, and add a couple new cards to our existing deck.
This does not actually work as expected, because only the new diamond cards will get added to our deck.
I am not proposing standardizing these methods to all return a new collection or the old collection. I think there is value in most of these methods, however, to provide both a way to return a new and the existing collection.
I'm not exactly sure how that looks yet, whether there is an additional parameter, or an entirely new method. That's what I'm hoping to get from this discussion.
There is one suggestion I'm guessing I'll hear, so I'll try and head it off. People will say why not just reassign the result to the original variable, which definitely works, and what I have to use now.
My biggest concern with this is lack of consistency, which adds to the developer's effort to comprehend the code. So if we go back to our
add
vsmerge
example, the code would look like this:While it looks relatively tame in this simplified example, it takes a second for the dev to ask, "why are we reassigning here, but not here? Oh yah, one returns a new collection and one returns the existing collection." If we can allow the developer to chose one mental model to stick, that's an improvement to me.
The second reason (and this could definitely be subjective) is it is less code to type and easier to read.
vs.
The third (and I'm not an expert in this, so if someone else know's better, please correct me), but my guess would be we're making PHP work a lot more currently. Rather than simply altering an existing object (which is passed by reference), PHP has to instantiate a new object, make the necessary alterations, and then reassign it to the variable.
Beta Was this translation helpful? Give feedback.
All reactions