I do not understand a thing.
In lua, functions can be passed variables, that contain information.
In a ulx command, the first variable passed, no matter how you specify it in the first line of your function setup, happens to be the calling player, the person that executed the command.
function ulx.ranks( calling_ply )
ply:PrintMessageSo, with your function setup, your passing the calling player to your function variable "calling_ply". That's fine, easy to see.
However, you're then trying to use "ply" in print message. That's not going to work. You're getting, or should be getting an error stating ply is null.