Externally stored code

Thalassicus

Bytes and Nibblers
Joined
Nov 9, 2005
Messages
11,057
Location
Texas
Any variable you use in the string portion, such as "f" above, is going to be a global variable.

This will not work:
Code:
local filename = "FEATURE_CRATER";
include (filename);
local className = "FeatureCrater";
local s = loadstring("f = className:new()");
s();
print(f:CanBe(10,5));
However, this will work:
Code:
local filename = "FEATURE_CRATER";
include (filename);
local className = "FeatureCrater";
local s = loadstring("f = "..className..":new()");
s();
print(f:CanBe(10,5));
The local variable className works properly, because it is evaluated for its value to add to the string, rather than being used as part of the string to be loaded. On the global level, className is nil, and you'd get errors stating such.

Okay, so I ran into a problem today where this would be helpful. I have a long table called BuildingStats where each value in the table is code to execute, and I would like to export it to XML for better modularity.

XML
Code:
<GameData>
  . . .
  <BuildingStats>
    <Row>
      <Type>Name</Type>
      <Value>(not bExcludeName)</Value>
    </Row>
	. . .

Lua
Code:
function GetHelpTextForBuilding(iBuildingID, bExcludeName, bExcludeHeader, bNoMaintenance)
  . . .
  for row in GameInfo.BuildingStats() do
    local statType = row.Type
    local statValue = loadstring(row.Value)
    statValue()
    . . .

This gives an error that loadstring is nil. How would I modify it to work as indicated in the first quote?
 
Programming In Lua describes the loadstring() function, taking a string and returning a function reference to a function defined using the chunk in the string; it mentions loadfile and a matching dofile that work as you're indicating, but I didn't see a mention of dostring.

However, it's possible that they just blocked that functionality for the lua extensibility in the game; it's not unusual, because it's sometimes seen as unsafe.
 
Ah, you were typing the reply as I deleted the post! :crazyeye:

I realized I asked almost the same question 3 months ago (link). My first thought was also that they blocked it, but JeBuS27 states the functions work if variable scope is handled properly. The problem is I'm not familiar enough with Lua to know how to modify my code to work.

dostring("stuff") is the same as loadstring("stuff")(), telling the interpreter to load a block of code and execute it. I'm assuming that's what LiveTuner uses since this is default lua stuff.
 
You can create a work-around for function values by storing your functions in a table and calling t["foo"], which is the same as t.foo

This won't work for your boolean chunks but you can just create wrapper functions for them, which is a cleaner way to solve the issue anyways
 
I did something like that when playing around with the emigration mod, but didn't think of creating an anonymous function for each value! That's a fantastic idea, thank you. :)
 
It is a beautiful and useful result of the way members/string-indexed values in tables work. A surprising amount of what look like more structured language constructs in Lua are syntactic sugar over very dynamic, unstructured constructs. The whole metatable thing, also, is very cool.
 
Back
Top Bottom