2

I'm essentially trying to create a function which tests the first location I give, in the form:

 myComputer.referenceLookup("/address/x/text")

and return the string in that location if it is not NULL or "None" or "" (empty).

If not, I want it to test the next possible location:

 myComputer.referenceLookup("/address/1/x/text")

Otherwise, I would like it to return an empty string ("").

I've tried looking in the Lua Manual to no avail as well as testing different forms in repl.it, but unfortunately, I can't replicate a similar example as I usually do when testing.

function firstLine(x)

if myComputer.referenceLookup("/Address/ .. (x) .. /text") != NULL or "None" or "" then

    return myComputer.referenceLookup("/Address/ .. (x) .. /text")

elseif myComputer.referenceLookup("/Address/1/ .. (x) .. /text") !=  NULL or "None" or "" then

    return myComputer.referenceLookup("/Address/1/ .. (x) .. /text")

else

    return ""

end

end

myComputer.out.firstHouseNumber = firstLine(housenumber)

It's worth noting that the usual way I would reference the fact is as follows:

myComputer.out.firstHouseNumber= myComputer.referenceLookup("/Address/housenumber/text")

or

myComputer.out.firstHouseNumber= myComputer.referenceLookup("/Address/1/housenumber/text")

The platform I'm using doesn't throw errors, it just will return blank instead of running the lua script so I am unable to debug (hence usually using repl.it).

I know this makes it a bit of an abstract question, but if anyone knows how I can do what I am describing, it would be very much appreciated.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Gamora
  • 337
  • 2
  • 18
  • when you say `return the string in that location` do you mean you are looking to read the text file and return the contents? or just return the validated path? -- Side note on your question: the lua example of firstLine is not valid lua. uses `NULL` rather than `nil`, `!=` rather than `~=`, and `"/Address/ .. (x) .. /text"` would not have the desired effect(it's missing some additional `"`) – Nifim Jun 18 '19 at 17:11
  • @Nifim, Ideally, return the string which is at that location, my mistake about the != and the ~=, I've been converting from the DSL which the system used to Lua and confusingly, the ~= is used as approx. equal! – Gamora Jun 19 '19 at 09:15

1 Answers1

2

Assumptions

Looking at your answer, I will assume that

  1. myComputer.referenceLookup is defined somewhere else and works as intended (and not part of this question)
  2. NULL is also defined somewhere else and represents some sort of nil-value

Answer

The line

if myComputer.referenceLookup("/Address/ .. (x) .. /text") != NULL or "None" or "" then

doesn't work, because the or operator doesn't work that way.

How Lua interprets it is

if (myComputer.referenceLookup("/Address/ .. (x) .. /text") != NULL) or "None" or ""

and since "None" is a String value and thus considered truthy, the if condition will always evaluate to true, so it will always return the first location. Also, there is no != operator in Lua; it's ~= instead.

As for a solution, you essentially need three comparisons like this:

if myComputer.referenceLookup("/Address/" .. x .. "/text") ~= NULL
and myComputer.referenceLookup("/Address/" .. x .. "/text") ~= "None"
and myComputer.referenceLookup("/Address/" .. x .. "/text") ~= "" then

Obviously calling the function three times is a bad idea, both because of performance and because it may have side effects, so it's better to save it into a variable first like so:

local result = myComputer.referenceLookup("/Address/" .. (x) .. "/text")
if result ~= NULL and result  ~= "None" and result  ~= "" then
  return result
end

Extra

If you want to make your program easier to extend, you can also use string.format to build the locations from templates. Say you have a table containing all your locations like this:

local locations = {
  "/Address/%s/text";
  "/Address/1/%s/text";
}

Then you can iterate through the entries using ipairs and build each location using string.format:

for index, template in ipairs(locations) do
  local result = myComputer.referenceLookup(template:format(x))
  if result ~= NULL and result  ~= "None" and result  ~= "" then
    return result
  end
end

Note that you can write string.format(template, x) as template:format(x) as long as template is a string. (further reading)

DarkWiiPlayer
  • 6,871
  • 3
  • 23
  • 38
  • Thanks very much for that! My mistake about the != and the ~=, I've been converting from the DSL which the system used to Lua and confusingly, the ~= is used as approx. equal! The Extra help is also greatly appreciated. – Gamora Jun 19 '19 at 09:16
  • Sorry, one more question! The location of the file is: myComputer.referenceLookup("/Address/example/text") not myComputer.referenceLookup(/Address/example/text). I.e. the quotation marks around the location. I'm wondering how that is going to work in this situation – Gamora Jun 25 '19 at 14:22
  • @Bee I don't really get what you mean by that, sorry. The example without the quotation marks would not be valid Lua syntax at all. – DarkWiiPlayer Jun 25 '19 at 15:22
  • That's basically what I'm saying, if you concat the bit inside the brackets as you have above, would it still return a string and therefore a valid address? I assume from your response that that is a yes, I'm fairly new to Lua so just trying to get my head around it! – Gamora Jun 25 '19 at 15:24
  • @Bee short answer: `"hello" .. "world"` is the exact same as `"helloworld"`, there's absolutely no difference. Long answer: [Official Reference, 3.4.6 – Concatenation](https://www.lua.org/manual/5.3/manual.html#3.4.6) – DarkWiiPlayer Jun 25 '19 at 17:02
  • Ok thanks, I was just wondering if it would work the same in a lookup, but I suppose it makes sense that it would. Thanks again! – Gamora Jun 25 '19 at 17:06