Understanding eval()
by Tim Doty · in Torque Game Builder · 04/11/2005 (4:03 pm) · 12 replies
I thought I had a grip on the eval() command, but I'm confused again. You can do:
What I'm trying to do is have an arbitrary function executed by an OO class. It works unless there are any math operations which poses a problem. If eval() is not intended for this is there a command to do so?
edit: should've cut & pasted instead of typing free hand...
==>eval("$t = $player.getLinearVelocity();");
==>echo($t);
0.000000 0.000494but not:==>eval("1+1;");
Syntax error in input.What I'm trying to do is have an arbitrary function executed by an OO class. It works unless there are any math operations which poses a problem. If eval() is not intended for this is there a command to do so?
edit: should've cut & pasted instead of typing free hand...
About the author
#2
NOTE: Just tested the above and it works.
==>echo($t);
2
04/11/2005 (4:34 pm)
You tried the following?eval("$t = 1+1;");NOTE: Just tested the above and it works.
==>echo($t);
2
#3
If you opened up the console and typed
I'm pretty sure you'd get an error.
04/11/2005 (4:34 pm)
Yeah as David said, eval is literally code you want to run. Think of whats inside eval to be direct code.If you opened up the console and typed
1+1;
I'm pretty sure you'd get an error.
#4
The work around is to do:
but this leaves open a problem of multiple objects using $tVal, potentially simultaneously. Or not, I just remembered that T2D is single threaded. Still, it makes me nervous. I suppose I could subscript as follows:
At least, I think it might work. You can pass local variables to eval(), just not set them (eval() would be setting them in a different scope).
Any comments?
04/11/2005 (5:02 pm)
Thanks everyone, I appreciate the information! As to why it was an issue consider this:%this.function = "$someSprite.getValue() * 10;"; ... %this.doSomeFunction(%param1, eval(%this.function));
The work around is to do:
%this.function = "$tVal = $someSprite.getValue() * 10;"; ... eval(%this.function); %this.doSomeFunction(%param1, $tVal);
but this leaves open a problem of multiple objects using $tVal, potentially simultaneously. Or not, I just remembered that T2D is single threaded. Still, it makes me nervous. I suppose I could subscript as follows:
%this.function = "$tVal[%this] = $someSprite.getValue() * 10;"; ... eval(%this.function); %this.doSomeFunction(%param1, $tVal[%this]);
At least, I think it might work. You can pass local variables to eval(), just not set them (eval() would be setting them in a different scope).
Any comments?
#5
Eval is actually quite simple. Its use is to allow you to programmaticly write code. You generate code and eval runs it as if you had typed it into the console.
04/11/2005 (5:30 pm)
I'm sorry but i'm not entirely sure what you are trying to do.Eval is actually quite simple. Its use is to allow you to programmaticly write code. You generate code and eval runs it as if you had typed it into the console.
#6
As David said, eval() doesn't evaluate an expression, it merely hands the interpreter a line literally as if you had typed it into the console. Which is fine.
04/11/2005 (5:36 pm)
@John: I can do what I need, I was just explaining how eval() works differs from my expectation and why I might even want such behavior.As David said, eval() doesn't evaluate an expression, it merely hands the interpreter a line literally as if you had typed it into the console. Which is fine.
#7
%this.function = "$someSprite.getValue() * 10;";
%this.doSomeFunction( %param1, eval("return" SPC %this.function) );
The return 'function' will let you avoid that nasty temporary variable!
04/03/2006 (4:06 pm)
I think what you were looking for is this, Tim:%this.function = "$someSprite.getValue() * 10;";
%this.doSomeFunction( %param1, eval("return" SPC %this.function) );
The return 'function' will let you avoid that nasty temporary variable!
#8
04/03/2006 (5:10 pm)
Dead on! I don't know why it didn't occur to me to use return. Thanks!
#9
I've been going nuts trying to figure an elegant way to store function calls in the DB on action, but I needed the return values...
This is a fantastic help, thanks everyone for the heads up on this...
Just a quick question though... Can I pass in a local variable as well?
For instance my "function" would look like....
%myfunction = "%player.Stat[%statname]++";
Would doing that increment the players stat at %statname for instance?
04/06/2006 (10:10 am)
Oh wow talk about nick of time on this thread...I've been going nuts trying to figure an elegant way to store function calls in the DB on action, but I needed the return values...
This is a fantastic help, thanks everyone for the heads up on this...
Just a quick question though... Can I pass in a local variable as well?
For instance my "function" would look like....
%myfunction = "%player.Stat[%statname]++";
Would doing that increment the players stat at %statname for instance?
#10
where %this is your player object.
04/06/2006 (4:23 pm)
@Dreamer: not if I remember correctly. You can pass the value of local variables in, but the eval() function operates in a different scope. Pass by value, not pass by reference. What you probably want is to use objects to keep state information, attach the function to an object and use the "%this" to then reference object variables. Roughly,%this.myFunction = "%this.Stat[%statname]++";
where %this is your player object.
#11
Any ideas ?
My eval statement keeps saying Syntax Error!
This is making me nuts.
Also we assume %result.PreReq ="%player.faction == %npc.faction" came through correctly which the debug spew shows did in fact come through correctly.
And the strreplace is doing it's job as well
04/07/2006 (12:10 pm)
Ok here is the code I'm using and yes it's bugged...Any ideas ?
function GetInteraction(%npc,%player){
//This is the First part of the quest system
//This function pulls the NPCInteractions from the DB,
//It then checks which Conversations the NPC & Player have had together
//Finally it determines which one should be next
//NPCInteractions (NPC,Says) VALUES ('Guard Kronk','1 2 4' );
%npcname = %npc.getShapeName();
if(%npc.Says $=""){
%result = DB::Select("Says", "NPCInteractions", "NPC = \'" @ %npcname @ "\'");
if(%result.NumRows() > 0){
%npc.Says = %result.Says;
%result.Clear();
}else{
return;
}
}
//At this point we want to loop through the interactions and compare them to the players Journal
for(%x = 0; %x <= getWordCount(%npc.Says); %x++){
%thisInteraction = getWord(%npc.Says, %x);
//%player = %npc.getAimObject();
if(%player.Journal[%npcname,%thisInteraction].status != 3){
//Here we have determined that the interaction has not been marked as complete in the players journal
//Now we want to pull the ConvoThread and make sure the player CAN do the interaction
//ConvoThreads(TID INT(11),PreReq TEXT,NPCSay TEXT,NPCDo TEXT);
%result = DB::Select("*", "ConvoThreads", "TID = \'" @ %thisInteraction @ "\'");
if(%result.NumRows() > 0){
%result.PreReq = strreplace(%result.PreReq,"%player",%player);
%result.PreReq = strreplace(%result.PreReq,"%npc",%npc);
echo("PreReq is "@%result.PreReq);
%toeval = "return if("@%result.PreReq@"){return(1);}";
echo("toeval is "@%toeval);
if(eval(%toeval)){
//The PreReq has evaluated as true, and the journal
//indicates we have not had this conversation before or it was never completed
//Therefore we need to setup the Say portion and Do the Do
//After that we clear the result and exit the function
PrepInteraction(%player,%npcname,%thisInteraction,%result.say);
eval(%result.NPCDo);
%result.Clear();
return;
}
%result.Clear();
}
}
}
}My eval statement keeps saying Syntax Error!
This is making me nuts.
Also we assume %result.PreReq ="%player.faction == %npc.faction" came through correctly which the debug spew shows did in fact come through correctly.
And the strreplace is doing it's job as well
#12
%toeval = "return " @ %result.PreReq @ ";";
if (eval(%toeval)) {
.
.
.
... and it will work.
04/07/2006 (12:48 pm)
One tiny little thing about eval -- it's a stickler for a trailing ";". Just do something like this:%toeval = "return " @ %result.PreReq @ ";";
if (eval(%toeval)) {
.
.
.
... and it will work.
Torque Owner Fenrir Wolf
Eval doesn't work like it does in some languages, where it is implicitly implied that the entire eval is wrapped in an assignment. (For example, %blah = eval ("2+2") would return 4 in %t.)
Evals are literal statements. It's actually better to think of Eval as less an evaluation and more as a on-the-fly code injection into the script bytecode engine. So, your example fails because "1+1;" by itself isn't valid by the TScript compiler.
Why not do something like eval("%t=1+1;") and then work with the returned value?