Apparently, the unacceptable practice of using parent_type to organize code has been spreading around BYOND. Most likely due to Forum_account's use of it in his libraries. This needs to be ended, before it gets any further out of hand.
First, lets cover the basic concept, then an overview of its pros and cons.
Simply put, the
parent_type variable can be set (at compile time only) to change a type:
obj/MyObject
parent_type=/mob
//Your /obj is now a /mob instead!
//"WTF?" is indeed the correct response here.
Pros:
+ Alternative (though not superior) organizational options
+ Save insignificant amounts of time when typing paths
Cons:
- Broken standards
- General confusion
- Less informative code
Lets look at some examples of the confusion this usage would cause:
obj/MyObject
parent_type=/mob
mob/verb/Find_Objs()
new/obj/MyObject(src.loc)
for(var/obj/O in world) world<<O
Even though this object is typed as /obj/MyObject, a loop trough all /objs in the world would
not find it, because it now exists as a /mob. However, if we were to search for its specific path
for(var/obj/MyObject/O in world) then it would still be found. We could also find it by looking for /mobs
for(var/mob/M in world).
obj/MyObject
parent_type=/mob
mob/verb/Variable_Confusion()
var/obj/MyObject/O=new
world<<O.key
Even though our "O" variable is typed as an /obj, it will
not be able to reference /obj specific variables. Instead, it would be able to reference the /mob's "key" variable. This becomes a much larger, more confusing issue the further you get into the production of your game, as you will have countless variables and/or procedures defined specifically for one type.
Another example, using top level /datums:
mob/verb/Null_Icons()
for(var/SomeType/S in world) S.icon=null
Using proper standards, /SomeType here should be considered a top level /datum. This causes several fundamental problems that a competent developer may be able to diagnose and/or resolve; top level /datums, like /SomeType, wouldn't exist "in world", and they don't have an icon variable (which even the compiler would complain about).
These are the correct standards that should be understood across BYOND. However, if we want to pointlessly break these standards, debilitating the common understanding of our code, we could use parent_type for a type conversion.
SomeType
parent_type=/obj
What would this accomplish? Well, it would make our for() loop work, by making our code over complicated and confusing in the process. Lets look at the correct way to handle such a setup:
obj/SomeType
mob/verb/Null_Icons()
for(var/obj/SomeType/S in world) S.icon=null
As you can see here, the most advantageous feature of using parent_type in this way is saving 4 keystrokes; /obj/SomeType vs /SomeType. Alternatively, you save a line when defining the type correctly, and your code becomes generally more informative and consistent with the commonly understood BYOND standards.
Lets throw in another example, based on a recent "tutorial":
gun
//vars & procs
parent_type=/obj
magazine
parent_type=/obj
ammunition
parent_type=/datum
Assuming proper formatting standards were being used, you would know that /gun/magazine and /gun/ammunition would have access to /gun class vars & procs. However, since parent_type is being used to change them to a base /obj and /datum, this actually wouldn't be the case. This example suffers from the same issues that I explained earlier, in the /obj to /mob example.
Moral of the story? Using parent_type in this way provides no real benefits, it makes your code less understandable, and it is never necessary. Don't use it!