I was expecting an output of Last array element is 9 But in stead it is -1, so empty.

Is the problem that I am actually pushing items onto a copy of my array, so no items are added to the original one declared in the mainloop? If so, what would be the correct way of doing this? Would I simply change the do_something routine to just pass on the same ref as it got in, like this:

Code

do_something_else($arrayref);

And then in the do_something_else subroutine, I would do something like

As you stated, the problem is indeed that you are pushing elements onto copies of your array, and your suggested fix would work. Looks like you have your issue covered.

Just to clarify in case you didn't realise, $#array will return the last elements index / subscript. If you had 1 element in your array, it would return 0. Since you have 0 elements in your array it logically returns -1.

Fair question, Fishmonger! And maybe you would approach the task differently:

This is a game-related "combat-simulator", and the var, or array, in question, is a list of all ships in the combat. I have different subroutines for things like target-selection, weaponsfire, AI-descision-making that all alters different data in the array. So the target-selection will affect the targeting-data of the ships, and the AI-descision-routines will modify other things etc etc etc.

I can understand that someone will hint at me getting good at OO at this point, but I don't have the time now.

Just to clarify in case you didn't realise, $#array will return the last elements index / subscript. If you had 1 element in your array, it would return 0. Since you have 0 elements in your array it logically returns -1.

I know ;) The surprise was not the -1 as such, but the lack of 9 :)

I WAS surprised the other day when I discovered that scalar @{ $array[$i]{data} } returned 0 in stead of -1, but that's just me :)

Your code indicates that you have a bigger problem with perl's lexical variables and their scope than you do with references.

There is no problem in mainloop. You create an empty array and pass a reference to "do_something".

In "do_something", you shift that reference into a new scalar variable called "$arrayref". So far so good. Now the command "my @array" creates a new array which will exist until you reach the end of "do_something" block. You then give it the value (currently empty) of the @array in mainloop. You then pass a reference to this array to "do_something_else". Again, you create a new variable called "$arrayref" and shift the new reference into it. You now create a new lexical array and assign it the value of the @array from do_something.

You push a reference to a hash into that array and return from "do_something_else." As soon as you return, the copy of the array which contains the hash goes out of existence! You now return from "do_something". Now its copy of @array goes out of existence also.

Then you repeat the sequence nine more times and print the original @array (which is still empty).

Refer to the "Private Variables" section of perlsub.

Code

perldoc perlsub

Note that the variables $array_ref are created and destroyed in exactly the same way as the @array variables. In former case, it is exactly whay you want.

I can understand that someone will hint at me getting good at OO at this point

Yes, that would be best.

Quote

But what kind of approach would you recommend for such a setup?

If you're not ready to go the OO route, then the next best approach would be to use a more complex hash data structure. Without detailed info on your app, I can't say how complex that hash should be.

I'd also keep the action at a distance issue to a minimum, which means I would only go 1 level. If you need to go down multiple child subs, then I'd make use of return statements and direct assignments.