Specify whever a lua parameter should be a copy or a reference - function

I'm wondering if there is a way to specify if the parameters of a lua function should be copied or just referenced. Color is an object representing a color.
For example, with this code
function editColor(col)
col.r = 0
print(tostring(col.r))
end
color = Color(255, 0, 0)
print(tostring(color.r))
editColor(color)
print(tostring(color.r))
Makes the output
255
0
0
So col is a "reference" to color, but this code:
function editColor(col)
col = Color(0, 0, 0)
print(tostring(col.r))
end
color = Color(255, 0, 0)
print(tostring(color.r))
editColor(color)
print(tostring(color.r))
Makes this output
255
0
255
So here the color is copied.
Is there a way to force a parameter to be copied or referenced? Just like the & operator in C++?

No, parameters in Lua are always passed by value (mirror). All variables are references however. In your second example in editColor you're overriding what the variable col refers to, but it's only for that scope. You'll need to change things around, maybe instead of passing in a variable to be reassigned, have the function return something and do your reassignment outside. Good luck.

This will do what you want. Put the variable that you want to pass by reference into a table. You can use a table to pass anything by ref, not just a string.
-- function that you want to pass the string
-- to byref.
local function next_level( w )
w.xml = w.xml .. '<next\>'
end
-- Some top level function that you want to use to accumulate text
function top_level()
local w = {xml = '<top>'} -- This creates a table with one entry called "xml".
-- You can call the entry whatever you'd like, just be
-- consistant in the other functions.
next_level(w)
w.xml = w.xml .. '</top>'
return w.xml
end
--output: <top><next\></top>

Lua is a bad language. Suffer its simplicity when you need to do something just a little complex.

Related

Is there a way of manipulating a global variable you use as an argument for a function in lua?

I'm trying to write some code into a function so that it can be easily reused whereby a global value is increased.
The issue is that there are several different globals that can be manipulated, and I need the function to be able to handle each one.
I thought I could simply put the global variable into the argument in the function but it doesn't seem to work. Probably because lua creates a copy of the global variable it takes.
Is there a way to make sure that the global variable it manipulates is not just a copy?
I have already tried to make sure that all the relevant variables remain local, but the problem is that they are all in a loop, and so need to remain outside the loop to be able to increment properly.
Right now I have to write a separate function for each case of incrementation which is a little unweildy, if bareable.
Right now I have to do something like this
foo_time_1 = 0
foo_time_2 = 0
function foo_time_1(var)
foo_time_1 += 2
if foo_time < 2 then
sfx(02)
end
end
function foo_time_2(var)
if foo_time_2 < 2 then
sfx(02)
end
end
This allows the code to run as intended, but Ideally I would like the code to look something like this:
foo_time = 0
foo_time_2 = 0
function foo_time_manipulator(global_var, len, sfx)
global_var += 2
if global_var < len then
play(sfx)
end
end
//so I can write
foo_time_manipulator(foo_time, 2, 02)
foo_time_manupulator(foo_time_2, 3, 02)
The problem with that is that the global variable doesn't change and so the sound effect loops continuously as every frame the function is re-read and it see that the global varaible remains at the value it was used as an argument, rather than the updated variable.
Sorry if this question has been poorly worded, it's a little difficult to articulate.
Is there any way in lua to be able to manipulate a global variable that is used as an argument?
A good qualifier may be that this code is being looped, and so requires an outside variable to act as a counter.
You can try this:
function foo_time_manipulator(global_var_name, len, six)
local global_var = _G[global_var_name]
global_var = global_var + 2
if global_var < len then
play(sfx)
end
end
and use it like this
foo_time_manipulator("foo_time", 2, 02)
foo_time_manupulator("foo_time_2", 3, 02)

How do I set a function to a variable in MATLAB

As a homework assignment, I'm writing a code that uses the bisection method to calculate the root of a function with one variable within a range. I created a user function that does the calculations, but one of the inputs of the function is supposed to be "fun" which is supposed to be set equal to the function.
Here is my code, before I go on:
function [ Ts ] = BisectionRoot( fun,a,b,TolMax )
%This function finds the value of Ts by finding the root of a given function within a given range to a given
%tolerance, using the Bisection Method.
Fa = fun(a);
Fb = fun(b);
if Fa * Fb > 0
disp('Error: The function has no roots in between the given bounds')
else
xNS = (a + b)/2;
toli = abs((b-a)/2);
FxNS = fun(xns);
if FxNS == 0
Ts = xNS;
break
end
if toli , TolMax
Ts = xNS;
break
end
if fun(a) * FxNS < 0
b = xNS;
else
a = xNS;
end
end
Ts
end
The input arguments are defined by our teacher, so I can't mess with them. We're supposed to set those variables in the command window before running the function. That way, we can use the program later on for other things. (Even though I think fzero() can be used to do this)
My problem is that I'm not sure how to set fun to something, and then use that in a way that I can do fun(a) or fun(b). In our book they do something they call defining f(x) as an anonymous function. They do this for an example problem:
F = # (x) 8-4.5*(x-sin(x))
But when I try doing that, I get the error, Error: Unexpected MATLAB operator.
If you guys want to try running the program to test your solutions before posting (hopefully my program works!) you can use these variables from an example in the book:
fun = 8 - 4.5*(x - sin(x))
a = 2
b = 3
TolMax = .001
The answer the get in the book for using those is 2.430664.
I'm sure the answer to this is incredibly easy and straightforward, but for some reason, I can't find a way to do it! Thank you for your help.
To get you going, it looks like your example is missing some syntax. Instead of either of these (from your question):
fun = 8 - 4.5*(x - sin(x)) % Missing function handle declaration symbol "#"
F = # (x) 8-4.5*(x-sin9(x)) %Unless you have defined it, there is no function "sin9"
Use
fun = #(x) 8 - 4.5*(x - sin(x))
Then you would call your function like this:
fun = #(x) 8 - 4.5*(x - sin(x));
a = 2;
b = 3;
TolMax = .001;
root = BisectionRoot( fun,a,b,TolMax );
To debug (which you will need to do), use the debugger.
The command dbstop if error stops execution and opens the file at the point of the problem, letting you examine the variable values and function stack.
Clicking on the "-" marks in the editor creates a break point, forcing the function to pause execution at that point, again so that you can examine the contents. Note that you can step through the code line by line using the debug buttons at the top of the editor.
dbquit quits debug mode
dbclear all clears all break points

MatLab fmin function

I have an .m file in matlab named PowerMinimiser and two functions in it
function PowerMinimiser
PowerOut = fmin(minFunction,0,100);
display(PowerOut)
end
and
function PowerOut = minFunction(varargin)
RunMode = 2;
ThresholdValue = 10;
if nargin > 0
ThresholdValue = varargin{1};
end
%Receive PowerOut value from .main file and pass in ThresholdValue and
%RunMode values:
[PowerOut] = main(ThresholdValue,RunMode);
end
Now what I would like to do is use the matlab fmin function so that I can find a value for the variable ThresholdValue which will give the lowest value possible for the variable PowerOut. The value for ThresholdValue is a number between 1 and 100, and is passed into a function in the main.m where a number of calculations are done and then a value for PowerOut is outputted.
Using the minFunction function I am able to receive and pass the variable fine, using the line
[PowerOut] = main(ThresholdValue,RunMode);
but I am not sure how to use the fmin function to get the value of ThresholdValue that gives the lowest value for PowerOut. I would like the ThresholdValue value to be shown once the fmin has done the necessary calculations. How can I do this? Any help would be greatly appreciated.
Thanks
You should use function fminbnd, which replaced fmin function in newer versions of Matlab. To pass function as an argument to fminbnd use # in front of the function name, like this:
PowerOut = fmin( #minFunction, 0, 100 );

Passing variables into a function in Lua

I'm new to Lua, so (naturally) I got stuck at the first thing I tried to program. I'm working with an example script provided with the Corona Developer package. Here's a simplified version of the function (irrelevant material removed) I'm trying to call:
function new( imageSet, slideBackground, top, bottom )
function g:jumpToImage(num)
print(num)
local i = 0
print("jumpToImage")
print("#images", #images)
for i = 1, #images do
if i < num then
images[i].x = -screenW*.5;
elseif i > num then
images[i].x = screenW*1.5 + pad
else
images[i].x = screenW*.5 - pad
end
end
imgNum = num
initImage(imgNum)
end
end
If I try to call that function like this:
local test = slideView.new( myImages )
test.jumpToImage(2)
I get this error:
attempt to compare number with nil
at line 225. It would seem that "num" is not getting passed into the function. Why is this?
Where are you declaring g? You're adding a method to g, which doesn't exist (as a local). Then you're never returning g either. But most likely those were just copying errors or something. The real error is probably the notation that you're using to call test:jumpToImage.
You declare g:jumpToImage(num). That colon there means that the first argument should be treated as self. So really, your function is g.jumpToImage(self, num)
Later, you call it as test.jumpToImage(2). That makes the actual arguments of self be 2 and num be nil. What you want to do is test:jumpToImage(2). The colon there makes the expression expand to test.jumpToImage(test, 2)
Take a look at this page for an explanation of Lua's : syntax.

LINQ-to-SQL oddity with multiple where clause arguments on the same field

My problem requires me to dynamically add where clauses to a IQueryable based on user input. The problem i'm having is that Linq-to-SQL doesn't seem to like having multiple where clauses on the same field, it actually duplicates the search arg value for the last item on all parameters. I verified this behavior through a SQL trace. Here is what I'm seeing.
WHERE ([t22].[OpenText] LIKE #p11) AND ([t22].[OpenText] LIKE #p12)
-- #p11: Input NVarChar (Size = 10; Prec = 0; Scale = 0) [%classify%] // Should be 2da57652-dcdf-4cc8-99db-436c15e5ef50
-- #p12: Input NVarChar (Size = 10; Prec = 0; Scale = 0) [%classify%]
My code uses a loop to dynamically add the where clauses as you can see below. My question is how do I work around this? This pretty much seems like a bug with the tool, no?
// add dyanmic where clauses based on user input.
MatchCollection searchTokens = Helper.ExtractTokensWithinBracePairs(filterText);
if (searchTokens.Count > 0)
{
foreach(Match searchToken in searchTokens)
query = query.Where((material => material.OpenText.Contains(searchToken.Value)));
}
else
{
query = query.Where((material => material.OpenText.Contains(filterText)));
}
Closing over the loop variable considered harmful! Change
foreach(Match searchToken in searchTokens) {
query = query.Where(
material => material.OpenText.Contains(searchToken.Value)
);
}
to
foreach(Match searchToken in searchTokens) {
Match token = searchToken;
query = query.Where(
material => material.OpenText.Contains(token.Value)
);
}
You are closing over the loop variable, which is considered harmful. To fix do this:
foreach(Match searchToken in searchTokens)
{
Match searchToken2 = searchToken;
// ^^^^^^^^^^^^ copy the value of the reference to a local variable.
query = query.Where(material => material.OpenText.Contains(searchToken2.Value));
// use the copy here ^^^^^^^^^^^^
}
The reason why your version doesn't work is that the query refers to the variable searchToken, not the value it had when the query was created. When the variable's value changes, all your queries see the new value.
I don't have enough rep to leave comments yet (or this would be a comment and not an answer) but the answers listed here worked for me.
However, I had to turn off compiler optimizations in order for it to work. If you do not turn off compiler optimizations (at least at the method level) then the compiler sees you setting a loop variable to a local variable and throws the local variable away.