Как определить функции в redis \ 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);
});
поэтому я получаю эту ошибку:
[Ошибка: ERR Ошибка запуска сценария (вызов.... @enable_strict_lua:7: user_script:1: Сценарий попытался создать глобальную переменную 'add']
поэтому я обнаружил, что это защита, как объясняется в этой теме:
"Строка документа scriptingEnableGlobalsProtection указывает на то, что цель состоит в том, чтобы уведомить авторов сценариев об общей ошибке (не используя local)".
но я так и не понял - где этот scripting.c? и решение изменения глобальных таблиц мне кажется рискованным.
Нет ли простого способа установки функций для redis - используя lua?
3 ответа
Это сработало для меня: (измените строку 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"
Похоже, что скрипт запускает ваш код в функции. Поэтому, когда вы создаете 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(...)
Вы должны назначить анонимную функцию переменной (используя локальную).
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 требует этого, чтобы предотвратить доступ к глобальной области. Весь механизм сценариев разработан так, чтобы не допускать постоянства на уровне сценариев. Разрешение вещей в глобальном масштабе создаст простой способ подорвать это, значительно усложняя отслеживание и управление состоянием на сервере.
Примечание: это означает, что вам придется добавлять одинаковые функции в каждый скрипт, который их использует. Они не постоянны на сервере.