2009-04-09 5 views
2

Это вопрос сценария WoW (World of Warcraft). Не многие из них задаются здесь, но у меня нет места для поворота, а Stackoverflow - это программный оазис для ответов.Что такое PCALL или Wowwiki неправильно?

Вопрос:

Wowwiki утверждает, что 2-й, 3-й, 4-й аргументы ваши вызова функции 1-й, 2-й, 3-й аргументы. Я не считаю это правдой. Я считаю, что 3-й, 4-й, 5-й аргументы становятся 1-м, 2-м, 3-м аргументами.

Ссылка: http://www.wowwiki.com/API_pcall

Функция:

function myTest(arg1) 
    return arg1 .. 10; 
end 

Проблема:

local retOK, ret1 = pcall(myTest,"string value"); 

, когда я пытаюсь образец я получаю ошибку «пытается выполнить СЦЕПИТЬ на местном 'arg1' (значение nil) ». Если я изменю код на:

local retOK, ret1 = pcall(myTest,"string value", "bob"); 

затем я получаю вывод «bob10». Куда идет второй аргумент и для чего он нужен?

Больше Тестирование:

function BobsToolbox:RunTest() 
    local test1, value1 = pcall(BobsToolbox.Test1, "string value"); 
    SharpDeck:Print("Test1: " .. tostring(test1) .. " Value: " .. tostring(value1)); 
end 

function BobsToolbox:Test1(arg1) 
    return arg1 .. "10"; 
end 

Результаты: попытка объединить местную 'arg1' (нилъ значение)

function BobsToolbox:RunTest() 
    local test1, value1 = pcall(Test1, "string value"); 
    SharpDeck:Print("Test1: " .. tostring(test1) .. " Value: " .. tostring(value1)); 
end 

function Test1(arg1) 
    return arg1 .. "10"; 
end 

Результаты: строка value10

Я новичок в Lua и я не могу понять, почему они разные.

Новый Вопрос:

Следующий код работает, но почему?

function BobsToolbox:RunTest() 
    local test1, value1 = pcall(BobsToolbox.Test1, "string value"); 
    SharpDeck:Print("Test1: " .. tostring(test1) .. " Value: " .. tostring(value1)); 
end 

function BobsToolbox.Test1(arg1) 
    return arg1 .. "10"; 
end 

В чем разница между следующими: (против "" ":")

  • функция BobsToolbox.Test1 (arg1)
  • функция BobsToolbox: Test1 (arg1)

ответ

6

Луа Документация:

http://www.lua.org/pil/16.html

Это использование параметра самого является центральной точкой в ​​любом объектно-ориентированном языке. В большинстве языков OO этот механизм частично скрыт от программиста, поэтому ей не нужно объявлять этот параметр (хотя она все еще может использовать слово self или this внутри метода). Lua также может скрыть этот параметр, используя оператор двоеточия. Мы можем переписать предыдущее определение метода как

function Account:withdraw (v) 
    self.balance = self.balance - v 
end 

и вызов метода, как

a:withdraw(100.00) 

Эффект от двоеточия, чтобы добавить дополнительный скрытый параметр в определении метода и добавить дополнительный аргумент в вызов метода. Двоеточие - только синтаксическое средство, хотя оно и удобно; здесь нет ничего нового.Мы можем определить функцию с точки синтаксисом и вызвать его с двоеточием, или наоборот, до тех пор, как мы обрабатываем дополнительный параметр правильно:

Account = { balance=0, 
    withdraw = function (self, v) 
     self.balance = self.balance - v 
    end 
} 

function Account:deposit (v) 
    self.balance = self.balance + v 
end 

Account.deposit(Account, 200.00) 
Account:withdraw(100.00) 

Возможные Вывод:

С этим в виду, я предполагаю, что при вызове функции «:» с использованием «pcall» вы должны указать аргумент «self».

+0

Да, похоже, вы нашли ответ! Когда вы создаете функцию BobsToolbox: Test1 (arg1), первый аргумент после имени функции, использующей pcall, как ожидается, будет объектом для работы. После этого аргумент является аргументом, который вы действительно хотите использовать. – Venesectrix

+0

Да, это кажется правильным. – AKX

1

Ну, я не думаю, что WoWWiki ошибается. Вот код, я использую:

function myTest(arg1) return arg1 .. 10; end 

local retOK, ret1 = pcall(myTest,"string value"); 
DEFAULT_CHAT_FRAME:AddMessage(ret1); 

local retOK, ret1 = pcall(myTest,"string value", "bob"); 
DEFAULT_CHAT_FRAME:AddMessage(ret1); 

Вот результат я получаю в моем General окне чата:

string value10 
string value10 

Как вы пытаетесь свой образец кода? Я только что вложил свой код в существующий файл mod lua и убедился, что мода включен в окне аддонов, прежде чем выбрать мой символ и войти в систему.Я сделал несколько изменений в файл Lua источника и напечатали:

/консоль reloadui

Чтобы попробовать новые изменения и выводимые результаты на мой экран. У меня нет большого совета, чтобы предложить вам, потому что я не много работал с WoW-аддонами. Вы пробовали этот код в пустой аддон, чтобы убедиться, что ничто другое не вмешивается? Вы действительно пробовали код в игре? Если вы можете предоставить дополнительную информацию или хотите, чтобы я попробовал что-нибудь еще, дайте мне знать!

Обновление: Решили попробовать еще несколько тестов. Вот тесты (с одной и той же функции):

local retOK, ret1 = pcall(myTest,""); 
DEFAULT_CHAT_FRAME:AddMessage(ret1); 

local retOK, ret1 = pcall(myTest, nil, "bob"); 
DEFAULT_CHAT_FRAME:AddMessage(ret1); 

И результаты:

10 
attempt to concatenate local 'arg1' (a nil value) 

Интересно, что ошибка я вижу, когда arg1 равен нулю немного отличается от этой ошибки. Мне было бы интересно узнать, как вы тестируете свой код. Или, может быть, вы не скопировали ошибку дословно? Я думаю, вы также можете попробовать очистить свою папку WTF и отключить остальные дополнения, чтобы проверить эту функцию. Если это имеет значение, вы можете включить их один раз, пока не найдете проблему.

+0

Приносим извинения, но я думаю, что я отказался от необходимой информации. В то время я не думал, что это важно. Если бы вы могли бы посмотреть, согласны ли вы с моей записью. –

2

Связанные: Есть хорошие редакторы живого кода для WoW. Раньше я использовал LuaSlinger, но, оказывается, он больше не разработан, и разработчик рекомендует вместо этого Hack.

Однако, что вы можете встретить здесь, так это то, что синтаксис вызова метода двоеточия - это просто синтаксический сахар, то есть для определения методов, IIRC. В принципе, если вы делаете foo:bar("quux!"), где foo - объект, вы на самом деле просто делаете foo.bar(foo, "quux!").

Надеюсь, что это поможет!

+0

Приносим извинения, но я думаю, что я отказался от необходимой информации. В то время я не думал, что это важно. Если бы вы могли бы посмотреть, согласны ли вы с моей записью. –