Skip to content

Rename get_many() to many(), making it consistent with single() #18615

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from

Conversation

BD103
Copy link
Member

@BD103 BD103 commented Mar 30, 2025

Objective

There is a pretty glaring inconsistency between Query::single() and Query::get_many()'s naming. Although they both return a Result, the later was not renamed into many(). This inconsistency is problematic because it makes it more difficult to developers to understand what it's doing.

Here's an example: across the Rust ecosystem, it's pretty much standard for conversion methods starting with as_ to be cheap, while methods starting with to_ to be expensive. (See str::as_bytes() vs. Path::to_str().) This is documented in the Rust API Guidelines, and is considered "good practice".

Bevy also has its own conventions and practices, I even wrote bevy_lint to help enforce these. Before better error handling was introduced, we had the following convention for panicking methods: get_foo() returned a Result, while foo() panicked. There are 17 examples of this in World, Query, and QueryState alone.

With Bevy 0.16, this convention is being changed. The panicking methods of old are no longer a thing, having been deprecated or replaced. Query::single() now returns a Result instead of panicking, with the old Query::get_single() being deprecated as an alias. This treatment wasn't given to Query::many(), however, because "folks weren't sold on the name many (get_many is clearer, and this is rare), and that PR is much more complex" (#18183).

Yes, the name get_many() is clearer that it returns a Result, but so is get_single()! Why should one method be given the ✨special✨ treatment just because it is more useful? There are too many parallels between single() and many() to cause such a large rift like this. For example, look at the Accessing query items table:

image

Even the wording is the same! The only differences are making "item" and "entity" plural.

So here's my point: developers will see the similarity between single() and get_many(), but will be confused why their naming is different when the do the exact same thing.

For additional context, see #18120 and #18183.

Solution

  • Delete the original panicking many() and many_mut().
  • Rename all get_many_*() methods (including get_many() and get_many_mut()) to many_*().
  • Create a new version of get_many() and get_many_mut() that are simply deprecated aliases to many() and many_mut(). (This is not needed for get_many_unique_mut() and friends because they are a new addition to 0.16.)
  • Fix all leftover references to get_many() and friends.

Testing

I relied heavily on cargo check, cargo test, and ripgrep to verify my changes were thorough. CI should catch anything I missed, but feel free to do you own checks!


Migration Guide

This migration guide should be merged with the original one that make Query::single() return a Result, and will replace #18183's migration guide.

Query::many() and Query::many_mut() (and the QueryState versions) now return a Result instead of panicking. Query::get_many() and Query::get_many_mut() are now deprecated.

BD103 added 7 commits March 29, 2025 20:04
All of these were found using ripgrep.
Remove references to `get_many()` and `get_many_mut()`. `single()` and `single_mut()` were also listed twice, so I deleted those as well.
@BD103 BD103 added A-ECS Entities, components, systems, and events C-Usability A targeted quality-of-life change that makes Bevy easier to use M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide X-Contentious There are nontrivial implications that should be thought through D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Mar 30, 2025
@BD103 BD103 added this to the 0.16 milestone Mar 30, 2025
Copy link
Contributor

It looks like your PR is a breaking change, but you didn't provide a migration guide.

Please review the instructions for writing migration guides, then expand or revise the content in the migration guides directory to reflect your changes.

@alice-i-cecile alice-i-cecile added X-Controversial There is active debate or serious implications around merging this PR and removed X-Contentious There are nontrivial implications that should be thought through labels Mar 30, 2025
@alice-i-cecile
Copy link
Member

You missed some in doc tests :) I'm going to mark this as X-Controversial. I'm in favor of this, but reverted it due to pushback in the linked PR.

@alice-i-cecile alice-i-cecile added S-Needs-SME Decision or review from an SME is required and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Mar 30, 2025
@NthTensor
Copy link
Contributor

I'm personally on side get_many/get_single rather than many/single, because it organizes all the accessors under the get_ prefix. But what matters here is consistency, so I'll take either.

@Victoronz
Copy link
Contributor

Victoronz commented Mar 30, 2025

My issue with this is that many should not be seen as a counterpart to single, but as a counterpart to get.
The name single is a bevy convention, and as a name and functionality, doesn't directly exist in std.
get_many is a name taken originally from slice::get_many_mut (there is no immutable counterpart in the stdlib).

Their names are counterparts in natural language, but that is not quite the case here! get/get_many more so align with iter/iter_many.

As an example, you show the docs of Query, but show get and get_many. I think my argument is clearer when including single in it:
grafik

get is "give me x"
get_many is "give me x, y, z in an array"

single more so represents "if length is 1, give me that item"

As a sidenote, the docs for Query are outdated, they should be updated with the new API surface.

@BD103
Copy link
Member Author

BD103 commented Mar 30, 2025

My issue with this is that many should not be seen as a counterpart to single, but as a counterpart to get.
The name single is a bevy convention, and as a name and functionality, and doesn't directly exist in std.
get_many is a name taken originally from slice::get_many_mut (there is no immutable counterpart in the stdlib).

Honestly, I'm convinced. The image I included even supports your argument lol; I must've been tired while writing up this PR.

In that case, I think this is a major documentation problem. We currently present single() and get_many() side-by-side, when really it should be get() and get_many(). I'm going to close this, then try to improve the docs as best as I can.

@BD103 BD103 closed this Mar 30, 2025
@BD103 BD103 deleted the many-consistency branch March 30, 2025 13:44
github-merge-queue bot pushed a commit that referenced this pull request Mar 31, 2025
# Objective

- There's been several changes to `Query` for this release cycle, and
`Query`'s top-level documentation has gotten slightly out-of-date.
- Alternative to #18615.

## Solution

- Edit `Query`'s docs for consistency, clarity, and correctness.
- Make sure to group `get()` and `get_many()` together instead of
`single()` and `get_many()`, to enforce the distinction from
#18615 (comment).
- Reformat doc tests so they would be readable if extracted into their
own file. (Which mainly involves adding more spacing.)
- Move link definitions to be nearer where they are used.
- Fix the tables so they are up-to-date and correctly escape square
brackets `\[ \]`.

## Testing

I ran `cargo doc -p bevy_ecs --no-deps` to view the docs and `cargo test
-p bevy_ecs --doc` to test the doc comments.

## Reviewing

The diff is difficult to read, so I don't recommend _just_ looking at
that. Instead, run `cargo doc -p bevy_ecs --no-deps` locally and read
through the new version. It should theoretically read smoother with less
super-technical jargon. :)

## Follow-up

I want to go through some of `Query`'s methods, such as `single()`,
`get()`, and `get_many()`, but I'll leave that for another PR.

---------

Co-authored-by: Chris Russell <[email protected]>
mockersf pushed a commit that referenced this pull request Mar 31, 2025
# Objective

- There's been several changes to `Query` for this release cycle, and
`Query`'s top-level documentation has gotten slightly out-of-date.
- Alternative to #18615.

## Solution

- Edit `Query`'s docs for consistency, clarity, and correctness.
- Make sure to group `get()` and `get_many()` together instead of
`single()` and `get_many()`, to enforce the distinction from
#18615 (comment).
- Reformat doc tests so they would be readable if extracted into their
own file. (Which mainly involves adding more spacing.)
- Move link definitions to be nearer where they are used.
- Fix the tables so they are up-to-date and correctly escape square
brackets `\[ \]`.

## Testing

I ran `cargo doc -p bevy_ecs --no-deps` to view the docs and `cargo test
-p bevy_ecs --doc` to test the doc comments.

## Reviewing

The diff is difficult to read, so I don't recommend _just_ looking at
that. Instead, run `cargo doc -p bevy_ecs --no-deps` locally and read
through the new version. It should theoretically read smoother with less
super-technical jargon. :)

## Follow-up

I want to go through some of `Query`'s methods, such as `single()`,
`get()`, and `get_many()`, but I'll leave that for another PR.

---------

Co-authored-by: Chris Russell <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Usability A targeted quality-of-life change that makes Bevy easier to use D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide S-Needs-SME Decision or review from an SME is required X-Controversial There is active debate or serious implications around merging this PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants