如何在Redis Lua中定义函数?

6

我正在使用Node.js和“redis-scripto”模块,并尝试在Lua中定义一个函数:

 var redis = require("redis");  
 var redisClient = redis.createClient("6379","127.0.0.1");   

 var Scripto = require('redis-scripto');
 var scriptManager = new Scripto(redisClient);
 var scripts = {'add_script':'function add(i,j) return (i+j) end add(i,j)'};

 scriptManager.load(scripts);
 scriptManager.run('add_script', [], [1,1], function(err, result){
                    console.log(err || result);
 });

我遇到了这个错误:

[错误:ERR 运行脚本时出错(调用.... @ enable_strict_lua:7:user_script:1:脚本尝试创建全局变量'add']

我发现这是一种保护措施,就像这个帖子中所解释的那样:

"scriptingEnableGlobalsProtection 的文档字符串表明其意图是通知脚本作者常见错误(不使用local)"

但我仍然不理解- scripting.c 是什么?而且更改全局表的解决方案对我来说似乎很危险。

有没有简单的方法可以使用lua将函数设置到redis中?

3个回答

7

看起来脚本运行器正在函数中运行您的代码。因此,当您创建function add()时,它会认为您是意外地在函数内部进行操作。它也可能会在调用add(i,j)时遇到类似的问题。 如果这是正确的,则应该可以这样解决:

local function add(i,j) return (i+j) end return add(1,1)

如果这样做成功了,希望您能够从js中传递参数,那么这也将成功。
local function add(i,j) return (i+j) end return add(...)

4
你需要将一个匿名函数分配给一个变量(使用local)。
local just_return_it = function(value) 
    return value
end 

--// result contains the string "hello world"
local result = just_return_it("hello world")

另外,您可以创建一个表格,并将函数添加为表格上的字段。这样可以更加面向对象。

local obj = {}

function obj.name()
    return "my name is Tom"
end

--// result contains "my name is Tom" 
local result = obj.name()

Redis需要这样做来防止访问全局范围。整个脚本机制的设计是为了将持久性保持在脚本层之外。允许全局范围内的事物会创建一种简单的方式来破坏这一点,使跟踪和管理服务器上的状态变得更加困难。

注意:这意味着您必须将相同的函数添加到每个使用它们的脚本中。它们不会在服务器上持久存在。


2
这对我有用:(将上面问题的第5行更改为以下内容):
var scripts = {
'add_script':'local function add(i,j) return (i+j) end return(add(ARGV[1],ARGV[2]))'};

要将变量传递给脚本,请使用KEYS[]和ARGV[],如redis-scripto指南中所述,并且在这里还有一个很好的示例:Lua:Redis用户指南


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接