Indexing the DataModel at a service's class name should create the service

So instead of this happening:

print(game.HttpService)
--> HttpService is not a valid member of DataModel

This would happen:

print(game.HttpService)
--> HttpService

Why? There are countless scripts which do this:

local Players = game:GetService('Players')
Players.PlayerAdded:connect(print)
for _, player in pairs(Players:GetPlayers()) do
  print(player)
end

Because the scripter was afraid some other object named ‘Players’ would be parented to the DataModel. This change would eliminate that possibility and make it acceptable just to do:

game.Players.PlayerAdded:connect(print)
for _, player in pairs(game.Players:GetPlayers()) do
  print(player)
end

Which is more readable.

Credit for this idea goes to sim0nsays.

1 Like

Huh? If Simon had the idea, he should forward it onto the appropriate Roblox team (or himself) and get it into the game!

Although this forum does seem like it’s the devs’ checklist for things to work on :slight_smile:

How is this feature supposed to work for services with Names that differ from their ClassNames, such as RunService? In my opinion, the whole idea goes against what is expected when indexing the child of an object.

In general, it’s a bad idea to use child indexing on anything exposed to other scripts (e.g. everything under the DataModel), because you can’t guarantee that the object wont be modified to change how it’s indexed. The whole reason I use GetService on Players is because it’s possible for the Players class to be renamed to something else. This should be considered especially so for things like CoreScripts, which should be written to never fail.

If you do want to be able to index services directly, then guarantee that every service is already available, that each service has its expected name, and that each service is the first child in the DataModel with the name. This should be so before any scripts are allowed to run. Doing this might break places which deliberately rename services for whatever reason, but you might already consider that bad practice. I think this would be a much better solution over adding an exception to how indexing works.

Another solution could be to add a property to DataModel for each service. Since properties have priority over children, there won’t be any conflicts or renaming issues. This is already done with Workspace. Yet another solution, which is also already done with Workspace, is to add a reference to each service in the global environment.

If that’s the reason behind this feature, then adding it wouldn’t do anything, because
indexing a child selects the first child with the given name, not the last. If you added the service after an object with the same name already existed, indexing the name would still select that first object!

I’d at least like intellisense to work with game:GetService()

I agree with Anaminus but go even further.

I think that GetService is the correct solution, and a way around using it should not be added. You have to be aware of the fact that services are lazily initialized when doing your coding: For instance, some services may take a non-trivial amount of time to create, I don’t like the idea of hiding that fact behind a normal property or dot operator which gives you the expectation that the service is already there and you’re just getting a reference to it, when that is not the case.