简体   繁体   English

如何在redis \\ lua中定义函数?

[英]how to define functions in redis \ lua?

I'm using Node.js, and the 'redis-scripto' module, and I'm trying to define a function in Lua: 我正在使用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);
 });

so I'm getting this error: 所以我收到这个错误:

[Error: ERR Error running script (call to .... @enable_strict_lua:7: user_script:1: Script attempted to create global variable 'add'] [错误:ERR错误运行脚本(调用.... @enable_strict_lua:7:user_script:1:脚本尝试创建全局变量'add']

so I've found that it's a protection, as explained in this thread : 所以我发现它是一种保护, 如本主题所述

"The doc-string of scriptingEnableGlobalsProtection indicates that intent is to notify script authors of common mistake (not using local)." scriptingEnableGlobalsProtection的doc-string表明intent旨在通知脚本作者常见错误(不使用本地)。”

but I still didn't understand - where is this scripting.c ? 但我仍然不明白 - 这个脚本在哪里? and the solution of changing global tables seems risky to me. 改变全局表的解决方案对我来说似乎有风险。

Is there no simple way of setting functions to redis - using lua ? 有没有简单的方法将函数设置为redis - 使用lua?

It looks like the script runner is running your code in a function. 看起来脚本运行器正在函数中运行您的代码。 So when you create function add() , it thinks you're doing it inside a function by accident. 所以当你创建function add() ,它会认为你是在意外地在函数内部进行的。 It'll also, likely, have a similar issue with the arguments to the call to add(i,j) . 它也可能与add(i,j)调用的参数有类似的问题。 If this is correct then this should work: 如果这是正确的,那么这应该工作:

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

and if THAT works then hopefully this will too with your arguments passed from the js: 如果这个工作,那么希望这也将与你从js传递的参数:

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

This worked for me: (change line 5 from the question above): 这对我有用:(从上面的问题改变第5行):

var scripts = {
'add_script':'local function add(i,j) return (i+j) end return(add(ARGV[1],ARGV[2]))'};

to pass variables to the script use KEYS[] and ARGV[], as explained in the redis-scripto guide and also there's a good example in here: " Lua: A Guide for Redis Users " 将变量传递给脚本使用KEYS []和ARGV [],如redis-scripto指南中所述,这里还有一个很好的例子:“ Lua:Redis用户指南

You have to assign an anonymous function to a variable (using local). 您必须为变量分配匿名函数(使用local)。

local just_return_it = function(value) 
    return value
end 

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

Alternately, you can create a table and add functions as fields on the table. 或者,您可以创建表并在表上添加函数作为字段。 This allows a more object oriented style. 这允许更面向对象的风格。

local obj = {}

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

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

Redis requires this to prevent access to the global scope. Redis要求这样做是为了防止访问全局范围。 The entire scripting mechanism is designed to keep persistence out of the scripting layer. 整个脚本机制旨在将持久性保留在脚本层之外。 Allowing things in the global scope would create an easy way to subvert this, making it much more difficult to track and manage state on the server. 允许全局范围内的事物将创建一种简单的方法来破坏它,使得在服务器上跟踪和管理状态变得更加困难。

Note: this means you'll have to add the same functions to every script that uses them. 注意:这意味着您必须为使用它们的每个脚本添加相同的功能。 They aren't persistent on the server. 它们在服务器上不是持久的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM