lua - loadfile is executing right away and i can't figure out why - lua

I was under the impression that doing something like this:
local f = assert (loadfile('/var/www/widgets/widgetlookup.lua'))('13')
would just load the contents of widgetlookup.lua into the variable "f" and then to run the code, i could do this:
f()
However, what's happening is that as soon as I load the file, it's executing. I know because widgetlookup.lua prints out a string with the results. Ultimately, I need to capture the results of the script in a variable
Can you tell me what I'm doing wrong? If you need to see the contents of widgetlookup.lua please just say the word and i will post. Just didn't want to clutter up the question with unnecessary information.
Thanks.
EDIT 1
I changed my code to look like this:
local f = assert (loadfile('/var/www/widgets/widgetlookup.lua'))
local p = f(13)
And now code waits to run until i hit the second line... but I need to know how to capture the output of the script as a variable....
print(p) current returns a null value.

You're calling it with that ('13') at the end.
You want this:
local f = assert (loadfile('/var/www/widgets/widgetlookup.lua'))

Related

Lua - Repeat until recurent table to except 'attempt to index a nil value'

Ok so i will show an exemple
I want do this :
local x = {}
repeat
-- wait function
until x.lel.ciao
But i've this error :
input:3: attempt to index a nil value (field 'lel')
So i can just do this :
local x = {}
repeat
-- wait function
until x.lel and x.lel.ciao
but if i've a long path how can i do ?
like :
x.lel.ciao.value1.title1.text1
i dont want do :
local x = {}
repeat
-- wait function
until x.lel and x.lel.ciao and x.lel.ciao.value1 and x.lel.ciao.value1.title1 and x.lel.ciao.value1.title1.text1
Someone have an idea ? like a function safepath(x.lel.ciao.value1.title1.text1)
Just like Egor's comment (thanks Egor), debug.setmetatable allows you to set a metatable for object type (not object instance).
This comes with an issue,
All the objects of that type will also inherit the mtatable.
This means, you will experience issues that will make your code harder to debug, as it is definitely important to get this kind of feedback from nil values.
Take in example the following code:
debug.setmetatable(nil, { __index = {} })
repeat
. . . -- Your code goes here
until x.lel.ciao.value1.title1.text1
function getFrom(data, value)
return date[value]
end
. . . -- More code
From this simple scope perspective, you might quickly see the issue, but imagine this code being buried by thousands of lines and functions.
You will eventually run into insanity as it only returns nil, which shouldn't happen at all because, well, you are sure your data variable has such value, right?
In order to avoid such thing from happening, you should safely do it like this:
debug.setmetatable(nil, { __index = {} })
repeat
. . . -- Your code goes here
until x.lel.ciao.value1.title1.text1
debug.setmetatable(nil, nil)
According to the Lua reference, setting a metatable to nil will remove the metatable, this way you will only temporally ignore feedback from nil while running inside the repeat loop.

How to determine if sysdig field exists or handle error if it doesn't

I'm using Sysdig to capture some events and have a small chisel (LUA script) to capture and format the events as necessary. On the on_init() I'm requesting fields like so :
f_field = chisel.request_field("<field>")
My question is how can I check if a field exists before requesting it? I'm going to use a new field only just released on 0.24.1 but ideally I'd like my chisel to continue to work on older versions of sysdig without this field. I've tried wrapping the call to chisel.request_field in a pcall() like so :
ok, f_field = pcall(chisel.request_field("<field>"))
and even implementing my own "get_field" function :
function get_field(field)
ok, f = pcall(chisel.request_field(field))
if ok then return f else return nil end
end
f_field = get_field("<field>")
if f_field ~= nil then
-- do something
end
but the error ("chisel requesting nonexistent field <field>") persists.
I can't see a way to check if a field exists but I can't seem to handle the error either. I really don't want multiple versions of my scripts if possible.
Thanks
Steve H
You're almost there. Your issue is in how you're using pcall. Pcall takes a function value and any arguments you wish to call that function with. In your example you're passing the result of the request_field function call to pcall. Try this instead..
ok, f = pcall(chisel.request_field, "field")
pcall will call the chisel method with your args in a protected mode and catch any subsequent errors.

php str_replace produces strange results

I am trying to replace some characters in a text block. All of the replacements are working except the one at the beginning of the string variable.
The text block contains:
[FIRST_NAME] [LAST_NAME], This message is to inform you that...
The variables are defined as:
$fname = "John";
$lname = "Doe";
$messagebody = str_replace('[FIRST_NAME]',$fname,$messagebody);
$messagebody = str_replace('[LAST_NAME]',$lname,$messagebody);
The result I get is:
[FIRST_NAME] Doe, This message is to inform you that...
Regardless of which tag I put first or how the syntax is {TAG} $$TAG or [TAG], the first one never gets replaced.
Can anyone tell me why and how to fix this?
Thanks
Until someone can provide me with an explanation for why this is happening, the workaround is to put a string in front and then remove it afterward:
$messagebody = 'START:'.$messagebody;
do what you need to do
$messagebody = substr($messagebody,6);
I believe it must have something to do with the fact that a string starts at position 0 and that maybe the str_replace function starts to look at position 1.

How to get the value from SPOP safely and test for value or null

I am currently doing 2 steps in my code and I just realized I can combine both steps in a LUA script.
I am doing:
SPOP on my set
calling a lua script to do other things.
The value from step#1 is being passed and stored in the local variable ele.
My lua script looks like:
local ele = KEYS[1]
local p = KEYS[2]
local u = KEYS[3]
if redis.call("SISMEMBER", u, ele) == 0 then
..
..
return "OK"
else
return "EXISTS"
end
How can I call SPOP from inside my lua script and store it in a variable.
I need to do:
local popped = redis.call("SPOP", "my-set-here")
I'm not sure if that will work, but then I have to check if it is null or has a value I guess. Just want to make sure I am following best practise.
BTW, as a side note, what is the fastest way to create and test lua scripts?
You can check the value of popped for non-nillness with something like:
if popped then
-- do something
end
As for developing Redis Lua scripts, have a look at Zerobrane's integration:
http://notebook.kulchenko.com/zerobrane/redis-lua-debugging-with-zerobrane-studio
https://redislabs.com/blog/zerobrane-studio-plugin-for-redis-lua-scripts/
Disclosure: I was involved in the integration effort ;)

lua overload table __tostring function

I have a simple problem: I would like to cause the print function in lua to print the contents of a table, rather than just the word "table" and a memory address. For example:
> tab = {}
> tab[1]="hello"
> tab[2]="there"
>
> print(tab)
table: 0x158ab10
--should be
1 hello
2 there
I am aware that I can get this effect by executing something like:
for i,v in pairs(tab) do print(i,v) end
but I would like it to happen simply when I execute print(tab) rather than having to write out a loop every time. can this be done?
You would need to set __tostring() on every table you created. An easier way would be to use a pretty printing technique.
See this link: http://lua-users.org/wiki/TableSerialization
You can do this by overriding the global tostring() function. This is what print() calls on its arguments.
If you do not want to do any coding, try out the Microlight library by Steve Donovan. You can use it as follows:
tostring = require "ml".tstring
tab = {"abc", 3.14, print, key="value", otherkey={1, 2, 3}}
print(tab) --> {"abc",3.14,function: 0x7f5a40,key="value",otherkey={1,2,3}}

Resources