Call function using variable in function name?

Runes of Magic/Radiant Arcana (http://www.runesofmagic.com)
Post Reply
Message
Author
noobbotter
Posts: 527
Joined: Fri Aug 31, 2012 1:15 pm

Call function using variable in function name?

#1 Post by noobbotter » Tue Sep 18, 2012 11:24 pm

I was wondering if there is a way to call a function using a variable? For example, suppose I have several functions created and they are named Func1, Func2, Func3 and Func4. And depending on what's going on, it will pull a value (1 thru 4) from a table... Is there a way to call the function named Func where i is the value I pulled from the table? Hope you understand what I'm looking for.

Also, suppose I have a table with multiple information in it for each record, how would I pull specific information for each record? for example, if I had:

Code: Select all

table = {
     {myindex="1", Npcname="Snoop the Stubborn", Npcx="123", Npcy="987", Npcz="456"}
     {myindex="2", Npcname="Mishlor", Npcx="321", Npcy="789", Npcz="654"}
}
(this is my first time working with tables. Does this look like it's formatted right?)

Suppose I target an NPC and it was "Mishlor." How would I match that to the specific record in the above table, and how would I then use the myindex, Npcx, or any of the other values associated with "Mishlor"?

Thanks.

BillDoorNZ
Posts: 446
Joined: Wed Aug 03, 2011 7:37 pm

Re: Call function using variable in function name?

#2 Post by BillDoorNZ » Tue Sep 18, 2012 11:45 pm

function pointers are always fun...but they are made easy by lua :)

Code: Select all

given:

function Func1()
  --do some stuff
end;

function Func2()
  --do some stuff
end;

function Func3()
  --do some stuff
end;

function Func4()
  --do some stuff
end;



method1:

local myFunctionPointer = nil;

if (someTest) then
  myFunctionPointer = Func1;  -- NOTE it is not Func1(), but Func1 - without the brackets!
elseif (someTest2) then
  myFunctionPointer = Func2;
elseif (someTest3) then
  myFunctionPointer = Func2;
elseif (someTest4) then
  myFunctionPointer = Func2;
end;

--execute the function
myFunctionPointer();




method2:

local functions = { Func1, Func2, Func3, Func4 };

local i = 1; --index of the function to execute

--execute it
functions[i]();


BillDoorNZ
Posts: 446
Joined: Wed Aug 03, 2011 7:37 pm

Re: Call function using variable in function name?

#3 Post by BillDoorNZ » Tue Sep 18, 2012 11:52 pm

noobbotter wrote: Also, suppose I have a table with multiple information in it for each record, how would I pull specific information for each record? for example, if I had:

Code: Select all

table = {
     {myindex="1", Npcname="Snoop the Stubborn", Npcx="123", Npcy="987", Npcz="456"}
     {myindex="2", Npcname="Mishlor", Npcx="321", Npcy="789", Npcz="654"}
}
(this is my first time working with tables. Does this look like it's formatted right?)

Suppose I target an NPC and it was "Mishlor." How would I match that to the specific record in the above table, and how would I then use the myindex, Npcx, or any of the other values associated with "Mishlor"?

Thanks.

Code: Select all


local match = nil;
local npcToFind = "Mishlor";

for k,v in pairs(table) do --this is 1 way to iterate over the table records
  if (v) then --just being safe and testing that v is no null - should prolly check for table too but am being lazy
    if (v.Npcname == npcToFind) then --could to a string.lower on this too to be safe
      match=v; --set the match variable to the current row
      break; -- stop iterating over the table and exit the for-loop
    end;
  end;
end;

if (match) then
  --do something with the npc. Note that 'match' is the row in the table, so match.NpcName will be "Mishlor" etc
  -- e.g.
  player:moveTo(CWaypoint(v.Npcx, v.Npcz, v.Npcy));
  player:target_NPC(v.Npcname);
end;


noobbotter
Posts: 527
Joined: Fri Aug 31, 2012 1:15 pm

Re: Call function using variable in function name?

#4 Post by noobbotter » Wed Sep 19, 2012 5:51 am

Awesome. Thanks for the quick answers. I like the second option for the function pointer. Using this info, hopefully it won't take me too awefully long to crank out the userfunction I'm going to make. Thanks a bunch. Once I start to get close to my userfunction doing what I intend, then I'll share and I'll ask further questions if I get into any roadblocks.

noobbotter
Posts: 527
Joined: Fri Aug 31, 2012 1:15 pm

Re: Call function using variable in function name?

#5 Post by noobbotter » Wed Sep 19, 2012 1:29 pm

I have a couple quick questions about the information you gave me. In this:

Code: Select all

for k,v in pairs(table) do --this is 1 way to iterate over the table records
  if (v) then --just being safe and testing that v is no null - should prolly check for table too but am being lazy
    if (v.Npcname == npcToFind) then --could to a string.lower on this too to be safe
      match=v; --set the match variable to the current row
      break; -- stop iterating over the table and exit the for-loop
    end;
  end;
end;
if I were running two different searches on the same table to check for equality, would I have to use a different variable for "k", "v", and "match" on the second one?

Also, if a function calls another function, I am assuming the local variables from the first one won't be available in the second one, unless I use them in parenthesis when calling the function?

To be more clear, if I had used the functions like was in the second post:

Code: Select all

given:

function Func1()
  --do some stuff
end;

function Func2()
  --do some stuff
end;

function Func3()
  --do some stuff
end;

function Func4()
  --do some stuff
end;


local functions = { Func1, Func2, Func3, Func4 };

local i = 1; --index of the function to execute

--execute it
functions[i]();
Would I want to define the functions with variables using different variable names like this:

Code: Select all

function Func1(t_Npcname, t_Npcx, t_Npcz, t_Npcy)
  --do some stuff
end;
then when I call the function, I would use something like this:

Code: Select all

functions[i](v.Npcname, v.Npcx, v.Npcy, v.Npcz);
Is that along the right lines?


Also had one question on this part:

Code: Select all

if (match) then
  --do something with the npc. Note that 'match' is the row in the table, so match.NpcName will be "Mishlor" etc
  -- e.g.
  player:moveTo(CWaypoint(v.Npcx, v.Npcz, v.Npcy));
  player:target_NPC(v.Npcname);
end;
if "match" is the matching row, then would I want to use "match.Npcname", "match.Npcx", etc... instead of "v.Npcname", "v.Npcx", etc...?

Thanks for the help.

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Call function using variable in function name?

#6 Post by rock5 » Wed Sep 19, 2012 1:57 pm

noobbotter wrote:if I were running two different searches on the same table to check for equality, would I have to use a different variable for "k", "v", and "match" on the second one?
I assume you mean like a 'for' loop inside a 'for' loop. Actually no. The variables defined in the 'for' command are automatically declared as 'local'. So the inner k,v would be different than the outer k,v. Unless you wanted to use the outer k,v values in the inner loop. In which case you would have to use different variables to tell them apart.
noobbotter wrote:Also, if a function calls another function, I am assuming the local variables from the first one won't be available in the second one, unless I use them in parenthesis when calling the function?
Yes that's correct. Usually you use global variables when you really need the variable to be global, otherwise normally a function accepts arguments for values it needs and instead of changing a global variable, it should return values.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Call function using variable in function name?

#7 Post by rock5 » Wed Sep 19, 2012 2:05 pm

noobbotter wrote:Would I want to define the functions with variables using different variable names like this:

Code: Select all

function Func1(t_Npcname, t_Npcx, t_Npcz, t_Npcy)
  --do some stuff
end;
It doesn't matter what the argument names are as they will be local to that function. So you can use the same names on all the functions.
noobbotter wrote:if "match" is the matching row, then would I want to use "match.Npcname", "match.Npcx", etc... instead of "v.Npcname", "v.Npcx", etc...?
Good pick up. Yes it should be match.Npcname etc.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

BillDoorNZ
Posts: 446
Joined: Wed Aug 03, 2011 7:37 pm

Re: Call function using variable in function name?

#8 Post by BillDoorNZ » Wed Sep 19, 2012 2:14 pm

noobbotter wrote:I have a couple quick questions about the information you gave me. In this:

Code: Select all

for k,v in pairs(table) do --this is 1 way to iterate over the table records
  if (v) then --just being safe and testing that v is no null - should prolly check for table too but am being lazy
    if (v.Npcname == npcToFind) then --could to a string.lower on this too to be safe
      match=v; --set the match variable to the current row
      break; -- stop iterating over the table and exit the for-loop
    end;
  end;
end;
if I were running two different searches on the same table to check for equality, would I have to use a different variable for "k", "v", and "match" on the second one?
I assume that what you want to do is search for an npc at a set of co-ordinates? So something like:

Code: Select all

--I'm gonna change your table definition a bit to make this simpler to read/write
__npcDatabase = {
     {index=2,name="Snoop the Stubborn", x=123, y=987, z=456, choiceOption="Varanas"},
     {index=1,name="Mishlor", x=321, y=789, z=654}
}


function FindNpcAt(_x, _y, _z, _distance)
	local result = nil;
	
	for k,v in pairs(__npcDatabase) do
	  if (v) then
		local dist = distance(_x, _z, _y, v.x, v.z, v.y);
		if (_distance >= dist) then
			result = v;
			break;
		end;
	  end;
	end;

	return result;
end;
noobbotter wrote:Also, if a function calls another function, I am assuming the local variables from the first one won't be available in the second one, unless I use them in parenthesis when calling the function?
That is indeed correct :)
noobbotter wrote:To be more clear, if I had used the functions like was in the second post:

Would I want to define the functions with variables using different variable names like this:

Code: Select all

function Func1(t_Npcname, t_Npcx, t_Npcz, t_Npcy)
  --do some stuff
end;
then when I call the function, I would use something like this:

Code: Select all

functions[i](v.Npcname, v.Npcx, v.Npcy, v.Npcz);
Is that along the right lines?
yes and no :)

if you want to to use the functions generically. i.e. you want all of those functions to be called based off an index into a table (functions[index](...)) then they all need to have the same interface. By this, I mean they all need to be able to accept the same parameters. Lua is quite lenient about this tho. You could in theory have different interfaces (parameters) for each function and try to sort out the mess that results from that. I don't recommend that.

Alternatively you could do something like:

Code: Select all

function SellStuff(_params)
  if (_params) then
    player:merchant(_params.name);
  else
    printf("No NPC was found to sell to!!!!\n");
  end;
end;

function TeleportToSomewhere(_params)
  if (_params) then
    player:target_NPC(_params.name);
    ChoiceOptionByName(_params.choiceOption);
    waitForLoadingScreen(60);
    ...
  else
    printf("No NPC was found to teleport!!!!\n");
  end;
end;

function Func3(_params)
  --do some stuff
end;

function Func4(_params)
  --do some stuff
end;

functions = {SellStuff, TeleportToSomewhere, Func3, Func4);

function DetermineWhatToDo()
  local npc = FindNpcAt(player.X, player.Z, player.Y, 200);

  functions[npc.index]();
end;

noobbotter wrote: Also had one question on this part:

Code: Select all

if (match) then
  --do something with the npc. Note that 'match' is the row in the table, so match.NpcName will be "Mishlor" etc
  -- e.g.
  player:moveTo(CWaypoint(v.Npcx, v.Npcz, v.Npcy));
  player:target_NPC(v.Npcname);
end;
if "match" is the matching row, then would I want to use "match.Npcname", "match.Npcx", etc... instead of "v.Npcname", "v.Npcx", etc...?

Thanks for the help.
Indeed :) And yw :)

noobbotter
Posts: 527
Joined: Fri Aug 31, 2012 1:15 pm

Re: Call function using variable in function name?

#9 Post by noobbotter » Wed Sep 19, 2012 7:58 pm

I appreciate all the input. My next set of questions aren't related to the title of this thread so I'm going to post that in a new thread. I already got off base by asking about tables in the same thread.

Post Reply

Who is online

Users browsing this forum: No registered users and 29 guests