LUA: Avoiding passing by reference
I'm just starting to learn LUA and I've got an issue that I'm unsure which way to "properly" solve.
When I pass a Defold vmath.vector3
to my function it appears to be passed by reference and is therefore altered.
If I multiply it by anything this is solved however.
Is there another more correct way to solve this? I don't want to modify the original vector that I pass as an argument.
function M.get_nearest_tile(x, y)
if y then -- if we've got 2 inputs, use x & y
x = math.floor(x / M.TILE_SIZE)
y = math.floor(y / M.TILE_SIZE)
return x, y
else -- if we've only got 1 input, use as vector
local vec = x * 1 -- multiplying by 1 to avoid modifying the real vector
vec.x = math.floor(vec.x / M.TILE_SIZE)
vec.y = math.floor(vec.y / M.TILE_SIZE)
return vec.x, vec.y
end
end
function lua reference arguments defold
|
show 3 more comments
I'm just starting to learn LUA and I've got an issue that I'm unsure which way to "properly" solve.
When I pass a Defold vmath.vector3
to my function it appears to be passed by reference and is therefore altered.
If I multiply it by anything this is solved however.
Is there another more correct way to solve this? I don't want to modify the original vector that I pass as an argument.
function M.get_nearest_tile(x, y)
if y then -- if we've got 2 inputs, use x & y
x = math.floor(x / M.TILE_SIZE)
y = math.floor(y / M.TILE_SIZE)
return x, y
else -- if we've only got 1 input, use as vector
local vec = x * 1 -- multiplying by 1 to avoid modifying the real vector
vec.x = math.floor(vec.x / M.TILE_SIZE)
vec.y = math.floor(vec.y / M.TILE_SIZE)
return vec.x, vec.y
end
end
function lua reference arguments defold
Where doesvector3
come from? Is this Roblox or so?
– Henri Menke
Nov 13 '18 at 22:15
Ah, sorry, I feel stupid. I thought it was from "math". It's from "vmath" which is used by Defold (game engine).
– Ghork
Nov 13 '18 at 22:18
1
According to the docs you can copy a vector usinglocal new = vmath.vector3(old)
defold.com/ref/vmath/#vmath.vector3:v1
– Henri Menke
Nov 13 '18 at 22:19
1
Nitpick: It is Lua, not LUA.
– britzl
Nov 14 '18 at 5:04
1
You would get the same kind of result when passing a table. As Henri Menke mentioned above it is non-trivial to copy a Lua table.
– britzl
Nov 14 '18 at 5:05
|
show 3 more comments
I'm just starting to learn LUA and I've got an issue that I'm unsure which way to "properly" solve.
When I pass a Defold vmath.vector3
to my function it appears to be passed by reference and is therefore altered.
If I multiply it by anything this is solved however.
Is there another more correct way to solve this? I don't want to modify the original vector that I pass as an argument.
function M.get_nearest_tile(x, y)
if y then -- if we've got 2 inputs, use x & y
x = math.floor(x / M.TILE_SIZE)
y = math.floor(y / M.TILE_SIZE)
return x, y
else -- if we've only got 1 input, use as vector
local vec = x * 1 -- multiplying by 1 to avoid modifying the real vector
vec.x = math.floor(vec.x / M.TILE_SIZE)
vec.y = math.floor(vec.y / M.TILE_SIZE)
return vec.x, vec.y
end
end
function lua reference arguments defold
I'm just starting to learn LUA and I've got an issue that I'm unsure which way to "properly" solve.
When I pass a Defold vmath.vector3
to my function it appears to be passed by reference and is therefore altered.
If I multiply it by anything this is solved however.
Is there another more correct way to solve this? I don't want to modify the original vector that I pass as an argument.
function M.get_nearest_tile(x, y)
if y then -- if we've got 2 inputs, use x & y
x = math.floor(x / M.TILE_SIZE)
y = math.floor(y / M.TILE_SIZE)
return x, y
else -- if we've only got 1 input, use as vector
local vec = x * 1 -- multiplying by 1 to avoid modifying the real vector
vec.x = math.floor(vec.x / M.TILE_SIZE)
vec.y = math.floor(vec.y / M.TILE_SIZE)
return vec.x, vec.y
end
end
function lua reference arguments defold
function lua reference arguments defold
edited Nov 13 '18 at 22:21
Henri Menke
7,62511327
7,62511327
asked Nov 13 '18 at 20:49
GhorkGhork
85
85
Where doesvector3
come from? Is this Roblox or so?
– Henri Menke
Nov 13 '18 at 22:15
Ah, sorry, I feel stupid. I thought it was from "math". It's from "vmath" which is used by Defold (game engine).
– Ghork
Nov 13 '18 at 22:18
1
According to the docs you can copy a vector usinglocal new = vmath.vector3(old)
defold.com/ref/vmath/#vmath.vector3:v1
– Henri Menke
Nov 13 '18 at 22:19
1
Nitpick: It is Lua, not LUA.
– britzl
Nov 14 '18 at 5:04
1
You would get the same kind of result when passing a table. As Henri Menke mentioned above it is non-trivial to copy a Lua table.
– britzl
Nov 14 '18 at 5:05
|
show 3 more comments
Where doesvector3
come from? Is this Roblox or so?
– Henri Menke
Nov 13 '18 at 22:15
Ah, sorry, I feel stupid. I thought it was from "math". It's from "vmath" which is used by Defold (game engine).
– Ghork
Nov 13 '18 at 22:18
1
According to the docs you can copy a vector usinglocal new = vmath.vector3(old)
defold.com/ref/vmath/#vmath.vector3:v1
– Henri Menke
Nov 13 '18 at 22:19
1
Nitpick: It is Lua, not LUA.
– britzl
Nov 14 '18 at 5:04
1
You would get the same kind of result when passing a table. As Henri Menke mentioned above it is non-trivial to copy a Lua table.
– britzl
Nov 14 '18 at 5:05
Where does
vector3
come from? Is this Roblox or so?– Henri Menke
Nov 13 '18 at 22:15
Where does
vector3
come from? Is this Roblox or so?– Henri Menke
Nov 13 '18 at 22:15
Ah, sorry, I feel stupid. I thought it was from "math". It's from "vmath" which is used by Defold (game engine).
– Ghork
Nov 13 '18 at 22:18
Ah, sorry, I feel stupid. I thought it was from "math". It's from "vmath" which is used by Defold (game engine).
– Ghork
Nov 13 '18 at 22:18
1
1
According to the docs you can copy a vector using
local new = vmath.vector3(old)
defold.com/ref/vmath/#vmath.vector3:v1– Henri Menke
Nov 13 '18 at 22:19
According to the docs you can copy a vector using
local new = vmath.vector3(old)
defold.com/ref/vmath/#vmath.vector3:v1– Henri Menke
Nov 13 '18 at 22:19
1
1
Nitpick: It is Lua, not LUA.
– britzl
Nov 14 '18 at 5:04
Nitpick: It is Lua, not LUA.
– britzl
Nov 14 '18 at 5:04
1
1
You would get the same kind of result when passing a table. As Henri Menke mentioned above it is non-trivial to copy a Lua table.
– britzl
Nov 14 '18 at 5:05
You would get the same kind of result when passing a table. As Henri Menke mentioned above it is non-trivial to copy a Lua table.
– britzl
Nov 14 '18 at 5:05
|
show 3 more comments
3 Answers
3
active
oldest
votes
Since you're returning x
and y
as two values, you could implement both branches the same way without modifying any tables:
function M.get_nearest_tile(x, y)
local newX, newY
if y then -- if we've got 2 inputs, use x & y
newX = math.floor(x / M.TILE_SIZE)
newY = math.floor(y / M.TILE_SIZE)
else -- if we've only got 1 input, use as vector
newX = math.floor(x.x / M.TILE_SIZE)
newY = math.floor(x.y / M.TILE_SIZE)
end
return newX, newY
end
You have a duplicate declaration ofx
andy
, while syntactically not incorrect, this will not work as intended.
– dualed
Nov 14 '18 at 0:05
@dualed: Got it. Fixed.
– luther
Nov 14 '18 at 0:27
1
This is the kind of non-Defold specific but obvious solution I was looking for.
– Ghork
Nov 14 '18 at 9:27
add a comment |
Defold provides a number of special data structures that are all very useful in game development:
- vector3 - vmath.vector3(x,y,z), useful for describing positions or direction in a 3D coordinate system
- vector4 - vmath.vector4(x,y,z,w), used for color, tint etc (red, green, blue, alpha)
- quat - vmath.quat() a quaternion describing a rotation
- matrix4 - vmath.matrix4() a 4x4 matrix of values. Useful for view and projection matrices among other things
All of the above are used by the Defold game engine, but you'll find the same kind of data structures in other game engines as well.
The data structures above have one thing in common: They are of the Lua type userdata
print(type(vmath.vector3())) -- "userdata"
User data is passed by reference always and that is why you're seeing the behaviour that you describe. Defold does provide ways to make copies though:
local copy = vmath.vector3(original) -- copy the vector3 'original'
local copy = vmath.vector4(original) -- copy the vector4 'original'
local copy = vmath.quat(original) -- copy the quaternion 'original'
local copy = vmath.matrix4(original) -- copy the matrix4 'original'
add a comment |
You already have a solution in your else
branch: you'll have to create a copy of your vectors before applying "modifying" operations to them.
In terms of other options, it may be possible to come up with a way to do using proxy tables, but it's going to be much more complex than just creating a copy.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53289289%2flua-avoiding-passing-by-reference%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Since you're returning x
and y
as two values, you could implement both branches the same way without modifying any tables:
function M.get_nearest_tile(x, y)
local newX, newY
if y then -- if we've got 2 inputs, use x & y
newX = math.floor(x / M.TILE_SIZE)
newY = math.floor(y / M.TILE_SIZE)
else -- if we've only got 1 input, use as vector
newX = math.floor(x.x / M.TILE_SIZE)
newY = math.floor(x.y / M.TILE_SIZE)
end
return newX, newY
end
You have a duplicate declaration ofx
andy
, while syntactically not incorrect, this will not work as intended.
– dualed
Nov 14 '18 at 0:05
@dualed: Got it. Fixed.
– luther
Nov 14 '18 at 0:27
1
This is the kind of non-Defold specific but obvious solution I was looking for.
– Ghork
Nov 14 '18 at 9:27
add a comment |
Since you're returning x
and y
as two values, you could implement both branches the same way without modifying any tables:
function M.get_nearest_tile(x, y)
local newX, newY
if y then -- if we've got 2 inputs, use x & y
newX = math.floor(x / M.TILE_SIZE)
newY = math.floor(y / M.TILE_SIZE)
else -- if we've only got 1 input, use as vector
newX = math.floor(x.x / M.TILE_SIZE)
newY = math.floor(x.y / M.TILE_SIZE)
end
return newX, newY
end
You have a duplicate declaration ofx
andy
, while syntactically not incorrect, this will not work as intended.
– dualed
Nov 14 '18 at 0:05
@dualed: Got it. Fixed.
– luther
Nov 14 '18 at 0:27
1
This is the kind of non-Defold specific but obvious solution I was looking for.
– Ghork
Nov 14 '18 at 9:27
add a comment |
Since you're returning x
and y
as two values, you could implement both branches the same way without modifying any tables:
function M.get_nearest_tile(x, y)
local newX, newY
if y then -- if we've got 2 inputs, use x & y
newX = math.floor(x / M.TILE_SIZE)
newY = math.floor(y / M.TILE_SIZE)
else -- if we've only got 1 input, use as vector
newX = math.floor(x.x / M.TILE_SIZE)
newY = math.floor(x.y / M.TILE_SIZE)
end
return newX, newY
end
Since you're returning x
and y
as two values, you could implement both branches the same way without modifying any tables:
function M.get_nearest_tile(x, y)
local newX, newY
if y then -- if we've got 2 inputs, use x & y
newX = math.floor(x / M.TILE_SIZE)
newY = math.floor(y / M.TILE_SIZE)
else -- if we've only got 1 input, use as vector
newX = math.floor(x.x / M.TILE_SIZE)
newY = math.floor(x.y / M.TILE_SIZE)
end
return newX, newY
end
edited Nov 14 '18 at 0:27
answered Nov 13 '18 at 23:20
lutherluther
1,268614
1,268614
You have a duplicate declaration ofx
andy
, while syntactically not incorrect, this will not work as intended.
– dualed
Nov 14 '18 at 0:05
@dualed: Got it. Fixed.
– luther
Nov 14 '18 at 0:27
1
This is the kind of non-Defold specific but obvious solution I was looking for.
– Ghork
Nov 14 '18 at 9:27
add a comment |
You have a duplicate declaration ofx
andy
, while syntactically not incorrect, this will not work as intended.
– dualed
Nov 14 '18 at 0:05
@dualed: Got it. Fixed.
– luther
Nov 14 '18 at 0:27
1
This is the kind of non-Defold specific but obvious solution I was looking for.
– Ghork
Nov 14 '18 at 9:27
You have a duplicate declaration of
x
and y
, while syntactically not incorrect, this will not work as intended.– dualed
Nov 14 '18 at 0:05
You have a duplicate declaration of
x
and y
, while syntactically not incorrect, this will not work as intended.– dualed
Nov 14 '18 at 0:05
@dualed: Got it. Fixed.
– luther
Nov 14 '18 at 0:27
@dualed: Got it. Fixed.
– luther
Nov 14 '18 at 0:27
1
1
This is the kind of non-Defold specific but obvious solution I was looking for.
– Ghork
Nov 14 '18 at 9:27
This is the kind of non-Defold specific but obvious solution I was looking for.
– Ghork
Nov 14 '18 at 9:27
add a comment |
Defold provides a number of special data structures that are all very useful in game development:
- vector3 - vmath.vector3(x,y,z), useful for describing positions or direction in a 3D coordinate system
- vector4 - vmath.vector4(x,y,z,w), used for color, tint etc (red, green, blue, alpha)
- quat - vmath.quat() a quaternion describing a rotation
- matrix4 - vmath.matrix4() a 4x4 matrix of values. Useful for view and projection matrices among other things
All of the above are used by the Defold game engine, but you'll find the same kind of data structures in other game engines as well.
The data structures above have one thing in common: They are of the Lua type userdata
print(type(vmath.vector3())) -- "userdata"
User data is passed by reference always and that is why you're seeing the behaviour that you describe. Defold does provide ways to make copies though:
local copy = vmath.vector3(original) -- copy the vector3 'original'
local copy = vmath.vector4(original) -- copy the vector4 'original'
local copy = vmath.quat(original) -- copy the quaternion 'original'
local copy = vmath.matrix4(original) -- copy the matrix4 'original'
add a comment |
Defold provides a number of special data structures that are all very useful in game development:
- vector3 - vmath.vector3(x,y,z), useful for describing positions or direction in a 3D coordinate system
- vector4 - vmath.vector4(x,y,z,w), used for color, tint etc (red, green, blue, alpha)
- quat - vmath.quat() a quaternion describing a rotation
- matrix4 - vmath.matrix4() a 4x4 matrix of values. Useful for view and projection matrices among other things
All of the above are used by the Defold game engine, but you'll find the same kind of data structures in other game engines as well.
The data structures above have one thing in common: They are of the Lua type userdata
print(type(vmath.vector3())) -- "userdata"
User data is passed by reference always and that is why you're seeing the behaviour that you describe. Defold does provide ways to make copies though:
local copy = vmath.vector3(original) -- copy the vector3 'original'
local copy = vmath.vector4(original) -- copy the vector4 'original'
local copy = vmath.quat(original) -- copy the quaternion 'original'
local copy = vmath.matrix4(original) -- copy the matrix4 'original'
add a comment |
Defold provides a number of special data structures that are all very useful in game development:
- vector3 - vmath.vector3(x,y,z), useful for describing positions or direction in a 3D coordinate system
- vector4 - vmath.vector4(x,y,z,w), used for color, tint etc (red, green, blue, alpha)
- quat - vmath.quat() a quaternion describing a rotation
- matrix4 - vmath.matrix4() a 4x4 matrix of values. Useful for view and projection matrices among other things
All of the above are used by the Defold game engine, but you'll find the same kind of data structures in other game engines as well.
The data structures above have one thing in common: They are of the Lua type userdata
print(type(vmath.vector3())) -- "userdata"
User data is passed by reference always and that is why you're seeing the behaviour that you describe. Defold does provide ways to make copies though:
local copy = vmath.vector3(original) -- copy the vector3 'original'
local copy = vmath.vector4(original) -- copy the vector4 'original'
local copy = vmath.quat(original) -- copy the quaternion 'original'
local copy = vmath.matrix4(original) -- copy the matrix4 'original'
Defold provides a number of special data structures that are all very useful in game development:
- vector3 - vmath.vector3(x,y,z), useful for describing positions or direction in a 3D coordinate system
- vector4 - vmath.vector4(x,y,z,w), used for color, tint etc (red, green, blue, alpha)
- quat - vmath.quat() a quaternion describing a rotation
- matrix4 - vmath.matrix4() a 4x4 matrix of values. Useful for view and projection matrices among other things
All of the above are used by the Defold game engine, but you'll find the same kind of data structures in other game engines as well.
The data structures above have one thing in common: They are of the Lua type userdata
print(type(vmath.vector3())) -- "userdata"
User data is passed by reference always and that is why you're seeing the behaviour that you describe. Defold does provide ways to make copies though:
local copy = vmath.vector3(original) -- copy the vector3 'original'
local copy = vmath.vector4(original) -- copy the vector4 'original'
local copy = vmath.quat(original) -- copy the quaternion 'original'
local copy = vmath.matrix4(original) -- copy the matrix4 'original'
answered Nov 14 '18 at 5:17
britzlbritzl
8,59462933
8,59462933
add a comment |
add a comment |
You already have a solution in your else
branch: you'll have to create a copy of your vectors before applying "modifying" operations to them.
In terms of other options, it may be possible to come up with a way to do using proxy tables, but it's going to be much more complex than just creating a copy.
add a comment |
You already have a solution in your else
branch: you'll have to create a copy of your vectors before applying "modifying" operations to them.
In terms of other options, it may be possible to come up with a way to do using proxy tables, but it's going to be much more complex than just creating a copy.
add a comment |
You already have a solution in your else
branch: you'll have to create a copy of your vectors before applying "modifying" operations to them.
In terms of other options, it may be possible to come up with a way to do using proxy tables, but it's going to be much more complex than just creating a copy.
You already have a solution in your else
branch: you'll have to create a copy of your vectors before applying "modifying" operations to them.
In terms of other options, it may be possible to come up with a way to do using proxy tables, but it's going to be much more complex than just creating a copy.
answered Nov 13 '18 at 21:36
Paul KulchenkoPaul Kulchenko
19.4k22540
19.4k22540
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53289289%2flua-avoiding-passing-by-reference%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Where does
vector3
come from? Is this Roblox or so?– Henri Menke
Nov 13 '18 at 22:15
Ah, sorry, I feel stupid. I thought it was from "math". It's from "vmath" which is used by Defold (game engine).
– Ghork
Nov 13 '18 at 22:18
1
According to the docs you can copy a vector using
local new = vmath.vector3(old)
defold.com/ref/vmath/#vmath.vector3:v1– Henri Menke
Nov 13 '18 at 22:19
1
Nitpick: It is Lua, not LUA.
– britzl
Nov 14 '18 at 5:04
1
You would get the same kind of result when passing a table. As Henri Menke mentioned above it is non-trivial to copy a Lua table.
– britzl
Nov 14 '18 at 5:05