ID:2110988
 
Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
I'm wondering if it would be possible to add the ability to directly modify proc arguments, sorta like pointers in C++, so that we can avoid having to create/copy a list and return said list every time to preserve variable changes in a proc chain.

Not sure on the details of how it would work, but if deemed feasible, I'm sure there are some people here who can offer some ideas.

Thanks.
Lists kind of are pointers right now.

mob/verb/Test()
var/list/my_list = list("One","Two")
ModifyList(my_list)
src << my_list.len
for(var/item in my_list)
src << item

proc/ModifyList(list/some_list)
if(some_list) some_list += "Three"


No copies needed, you can actually do this with the 'vars' list too, it's sneaky stuff.
In response to Nadrew
True. Having to use a list seems very bulky in some cases though.

Here's the case I was considering when I posted this:

// attempting to receive damage from attacker.
proc/on_damage(combatant/attacker, stam_dmg=0, dmg_source, dmg_source_dir, params[])
if(stam_dmg <= 0 || action == global.actions[ACTION_DEATH])
return 0

var/damage_params[] = args.Copy()
if(has_event(EVENT_ON_DAMAGE) && !can_trigger_event(EVENT_ON_DAMAGE, src, damage_params))
return 0
. = round(damage_params[2])
// continues from here...


In this case, I'm copying the args list because I need stam_dmg preserve changes through the event chain. Granted, I could leave out the information I don't need by doing damage_params = list(stam_dmg), but I'd much rather avoid having to use lists this way if possible. And so this topic came to mind.
This feature request is for the ability to pass variables by reference. Normally, you can't actually pass a variable to a proc; when you write SomeProc(some_variable), some_variable is evaluated and the result -- the value contained in some_variable -- is passed to the proc. But what if you want to pass in a variable to be modified from inside the called proc?

C# does it with the "ref" or "out" keyword:
class RefExample
{
static void Method(ref int i)
{
i = i + 44;
}

static void Main()
{
int val = 1;
Method(ref val);
Console.WriteLine(val);

// Output: 45
}
}

In DM, you currently have to "box" the value to a reference type, such as a list or a datum:
mob
proc/Method(BoxedNumber[])
BoxedNumber[1] += 44

Login()
var boxed_number[] = list(1)
Method(boxed_number)
world << boxed_number[1]

// or
boxed_value
var value
New(Value) value = Value

mob
proc/Method(boxed_value/N)
N.value += 44

Login()
var boxed_value/n = new (1)
Method(N)
world << N.value

A common usage for this in Unity is when you want to test for raycasts. If you cast a ray, the function returns true if the ray hits something, and the given "out" variable is assigned information about the hit.
RaycastHit hit; // contains information about a hit, if any

if (Physics.Raycast(transform.position, -Vector3.up, out hit, 100.0f))
print("Found an object - distance: " + hit.distance);
In response to Kaiochao
Exactly this post.