Retrieving A Function From A WebhookScript Global Variable - function

In WebhookScript, I can store a function in a variable with:
sub = function(a, b) {
return a - b
}
I'd like to store a function in a Global Variable so that I can use it in multiple Custom Actions. But if I've saved the above function as $sub$ then
sub2 = var('$sub$')
subX = sub(1,2)
causes an error:
Trying to invoke a non-function 'string' # line...
And
function subX(a,b){
var('$sub$')
}
when sub only contains return a - b, doesn't work either.
Obviously I need to convert the string to a function but I'm not sure whether that's possible.
I know this is a bit of an obscure language but if anyone knows how this can be done in similar languages like JavaScript and PHP, I'm happy to test out any guesses...

The solution here is to remove the function section and just enter the script, which inherits the execution scope so if my global variable $script$ is:
return 'hello ' + a
Then I can execute the function with:
a = 'world'
value = exec(var('$script$'))
echo(value)
(credit to Webhook.Site's support team for explaining this)

Related

How to pass an object as argument to an anonymous function in MATLAB?

I'm working on a MATLAB app that programatically creates anonymous functions to evaluate any native MATLAB function and pass it a list of variables as argument. In the example below, 'formula' contains a string with the function and arguments to be evaluated (e.g., "sum( var1, var2 )" ). The formulas sometimes contain function calls nested within function calls, so the code below would be used recursively until obtaining the final result:
Func2 = str2func( sprintf( '#(%s) %s', strjoin( varNames, ',' ), formula ) );
This evaluates fine for native MATLAB functions. But there's a particular case of a function (named Func1) I made myself that not only needs the list of variables but also an object as argument, like this:
function output = Func1( anObject, varNames )
% do some stuff with the object and the vars
end
For this particular function, I've tried doing this:
Func2 = str2func( sprintf( '#(%s,%s) %s', "objectToPassToFunc1", strjoin( varNames, ',' ), "Func1(objectToPass,""" + strjoin( varNames, '","' ) +""")" ) )
...which doesn't throw an error, but Func1 doesn't receive the objectToPassToFunc1, instead it gets values from one of the variables in varNames. And I don't know why.
So how can I correctly pass the object to Func1????
Matlab doesn't care about the type of arguments you pass to a function. As a matter of fact, the input could be scalar, vector, matrix, and even an object of a class. See the following example.
classdef ClassA
methods
function print(~)
disp('method print() is called.');
end
end
end
This class has only one method. Now, let us define an anonymous function func which accepts one input.
func = #(arg) arg.print;
Notice that we explicitly assume that the input is an object of ClassA. If you pass another type of data to this function, Matlab will throw an error. To test the code,
obj = ClassA;
func = #(arg) arg.print;
func(obj)
To avoid the error, you may need to check the type of the input before using it. For example,
function [] = func(arg)
% check if arg is an object of ClassA
if isa(arg,'ClassA')
arg.print;
end
end
Now you can pass different types for the input without getting an error.

How to implement a basic Lua function in Conky?

I am trying to add a function to my Conky which prints the length of a string for debug purposes. The code, inside a file called test.lua, is pretty trivial:
function test(word)
return string.len(word)
end
...and I load it like this. In my conky.config section I have:
lua_load = '/home/xvlaze/test.lua',
lua_draw_hook_pre = 'test'
...in the conky.text section I have:
${lua test "fooo"}
...where test is the name of the function and fooo the string to test.
The expected result should be a printed 4 in Conky, but instead of that I get:
conky: llua_do_call: function conky_test execution failed: /home/xvlaze/test.lua:2: attempt to index a nil value (local 'string')
conky: llua_getstring: function conky_test didn't return a string, result discarded
I have browsed through the documentation, but I can't find anything. Does anybody know where the failure is?
Several guidances on how to implement functions in Conky:
First of all: YOU MUST USE conky_ BEFORE YOUR FUNCTION'S NAME.
Otherwise, you will get the following error when running your Conky:
attempt to call a nil value
Secondly: YOU MUST ALWAYS RETURN A VALUE.
I don't mind repeating it - it is crucial. Otherwise, you will get:
function foobar didn't return a string, result discarded
function_result
...in your terminal, and your Conky will be left empty of values related to your extra code. Nothing will be printed regarding your function.
Last but not least: YOU MUST ALWAYS CALL YOUR FUNCTION LIKE:
lua_load = '/path/to/function.lua',
-- Whatever content...
${lua function_name function_parameter1 function_parameterN} -- In case you use more than one parameter.
In summary, a dummy function template could be:
MAIN FILE (conky.conf):
conky.config = {
-- Whatever content... Lua styled comments.
lua_load = '/path/to/function.lua',
}
conky.text = [[
# Whatever content... In this section comments are started with '#'!
${lua function_name parameter}
]]
FUNCTION FILE:
function conky_function_name(parameter)
-- Whatever content... Remember this is Lua, not conky.text syntax. Always use '--' comments!
return whatever -- No return, no party. A function MUST always return something!
end

Calling the function name

As a beginner in Lua, I am sorry if the answer on this is easy.
I was trying to call a function within a code, yet after 2 hours of searching I couldn't find the wanted results. (Maybe I use the wrong search query's?)
Example code
function Test123 ()
SayTest = True
if SayTest = True then
-- This Is where I want to call the function name Test123,
-- yet I can't seem to succeed in this since it is just
-- starting a new function
SystemNotice ( role, function)
end
end
This should be the result:
function Test123 ()
SayTest = True
if SayTest = True then
SystemNotice ( role, 'Test123')
end
end
If anyone can help me out, I would be thankful. If I am still being unclear, just tell me and I will try to describe it better. My excuses for my limited English.
In Lua functions are actually values. That means they do not really have a name, you can only assign them to a variable or table field, but since the value itself has no concept of its name, you can't retrieve it.
That said, with the debug library, you can do this:
function getfname()
return debug.traceback("", 2):match("in function '(.-)'");
end
function bar()
print(getfname())
end
bar(); -- prints bar
foo = bar;
foo() -- prints foo
knerf = {rab = bar};
knerf.rab() -- prints rab
Note that this only works with the default Lua error handler or one that returns the same or very similar output, however you can obviously modify the pattern to suit what you need.
Read this: I would not advise this solution for performance-intensive tasks. Both string matching and the traceback are not really suited for this. Also, obviously the debug library must be enabled so you can actually use the traceback function.
Your function declaration lacks anend.
function Test123 ()
end
Read the functions chapter from the Lua manual. Just for the record, your if will also need an end.
This is a construct that just goes against the Lua philosophy that functions are first class citizens:
a function is just another value, and as such it has no name.
A variable can be assigned a value, thus binding a function to a name.
But that name can change. or a function can have multiple names. Which one to pick?
A better solution would be creating an anonymous function with an upvalue (a closure) instead:
function genTest(name)
return function()
SayTest = true
if SayTest == true then
print ( 'role', name)
end
end
end
Test123 = genTest('Test123')
Test123()
foobar = Test123
foobar()
This creates a function with a bound local variable name (see PiL 6.1 ).

Lua - Execute a Function Stored in a Table

I was able to store functions into a table. But now I have no idea of how to invoke them. The final table will have about 100 calls, so if possible, I'd like to invoke them as if in a foreach loop. Thanks!
Here is how the table was defined:
game_level_hints = game_level_hints or {}
game_level_hints.levels = {}
game_level_hints.levels["level0"] = function()
return
{
[on_scene("scene0")] =
{
talk("hint0"),
talk("hint1"),
talk("hint2")
},
[on_scene("scene1")] =
{
talk("hint0"),
talk("hint1"),
talk("hint2")
}
}
end
Aaand the function definitions:
function on_scene(sceneId)
-- some code
return sceneId
end
function talk(areaId)
-- some code
return areaId
end
EDIT:
I modified the functions so they'll have a little more context. Basically, they return strings now. And what I was hoping to happen is that at then end of invoking the functions, I'll have a table (ideally the levels table) containing all these strings.
Short answer: to call a function (reference) stored in an array, you just add (parameters), as you'd normally do:
local function func(a,b,c) return a,b,c end
local a = {myfunc = func}
print(a.myfunc(3,4,5)) -- prints 3,4,5
In fact, you can simplify this to
local a = {myfunc = function(a,b,c) return a,b,c end}
print(a.myfunc(3,4,5)) -- prints 3,4,5
Long answer: You don't describe what your expected results are, but what you wrote is likely not to do what you expect it to do. Take this fragment:
game_level_hints.levels["level0"] = function()
return
{
[on_scene("scene0")] =
{
talk("hint0"),
}
}
end
[This paragraph no longer applies after the question has been updated] You reference on_scene and talk functions, but you don't "store" those functions in the table (since you explicitly referenced them in your question, I presume the question is about these functions). You actually call these functions and store the values they return (they both return nil), so when this fragment is executed, you get "table index is nil" error as you are trying to store nil using nil as the index.
If you want to call the function you stored in game_level_hints.levels["level0"], you just do game_level_hints.levels["level0"]()
Using what you guys answered and commented, I was able to come up with the following code as a solution:
asd = game_level_hints.levels["level0"]()
Now, asd contains the area strings I need. Although ideally, I intended to be able to access the data like:
asd[1][1]
accessing it like:
asd["scene0"][1]
to retrieve the area data would suffice. I'll just have to work around the keys.
Thanks, guys.
It's not really clear what you're trying to do. Inside your anonymous function, you're returning a table that uses on_scene's return value as keys. But your on_scene doesn't return anything. Same thing for talk.
I'm going to assume that you wanted on_scene and talk to get called when invoking each levels in your game_level_hints table.
If so, this is how you can do it:
local maxlevel = 99
for i = 0, maxlevel do
game_level_hints.levels["level" .. i] = function()
on_scene("scene" .. i)
talk("hint" .. i)
end
end
-- ...
for levelname, levelfunc in pairs(game_level_hints.levels) do
levelfunc()
end

subfunctions in vim

I created a lot of functions in menu.vim.
I noted that in many functions the same code is used that's why I decided to clean up my file with the use of
subfunctions.
p.e this is code what often returns in my functions:
let zoek = #/
if a:type == "'<,'>"
let r = substitute(zoek, '\\%V', '', 'g')
elseif a:type == "%"
let r = zoek
endif
let a = substitute(r, '\', '', 'g')
if matchstr(d, '>') == '>' || matchstr(d, '<') == '<'
let e = substitute(d, '\zs>\(\d\+\)%<\ze', '\1-', 'g')
endif
How can I create a subfunction from it? How can I invoke it?
Does Vim have subfunctions?
You can have «local» functions by defining them in the dictionary: in the following code
function MyFunc()
let d={}
function d.function()
echo "Foo"
endfunction
call d.function()
endfunction
function d.function is accessible only inside s:MyFunc and is destroyed after s:MyFunc exits. I put «local» in quotes because d.function is really global function named 42 (or another number, it does not matter). It cannot be called without a reference to it and the only way to create a reference is to use function dict.key() (references may be copied after creation, but you can't create a reference using call to function(), though it is possible for MyFunc: function("MyFunc")). Note that number (in this case 42) is incremented each time you create a function and I know neither what is the maximum number nor what will happen when it will be reached. I personally use dictionary functions because they have two other advantages:
Dictionary function defined inside a script-local dictionary cannot be reached without a debugger or explicit passing the function reference (possibly as a part of its container) somewhere.
If more then one function is defined inside a dictionary in order to purge them all you need is to unlet this dictionary. Useful for reloading plugins.
There is only one type of function in Vimscript, but I'm not sure if this is what you are already using in your menu.vim. A user-defined function is defined thus:
function! MyNewFunction()
" your code here
endfunction
You can then call this function elsewhere in your scripts (and inside other functions) using
call MyNewFunction()
Or set a variable equal to the return value of your function using
let my_variable = MyNewFunction()
Of course this is an incredibly simplistic overview, since you say your are already using functions. Much more information, including the use of variables, here:
help user-functions
Apologies if I have not answered your question.