Что с PCALL или Wowwiki не так? - PullRequest
2 голосов
/ 09 апреля 2009

Это вопрос сценария lua для WoW (World of Warcraft). Не многих из них спрашивают здесь, но мне некуда обратиться, и Stackoverflow - это оазис программиста для ответов.

Вопрос:

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 

Результаты: строковое значение 10

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

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

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

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

В чем разница между следующим: ("." Vs ":")

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

Ответы [ 3 ]

6 голосов
/ 09 апреля 2009

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

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

Такое использование параметра self является центральной точкой в ​​любом объектно-ориентированном языке. В большинстве ОО-языков этот механизм частично скрыт от программиста, поэтому ей не нужно объявлять этот параметр (хотя она все еще может использовать слово 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".

2 голосов
/ 09 апреля 2009

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

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

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

1 голос
/ 09 апреля 2009

Ну, я не думаю, что 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);

Вот вывод, который я получаю в окне общего чата:

string value10
string value10

Как вы пробуете свой пример кода? Я просто вставил свой код в существующий файл мода 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 равен nil, немного отличается от ошибки, которую вы видите. Мне было бы интересно узнать, как вы тестируете свой код. Или, может быть, вы не скопировали ошибку дословно? Я думаю, вы также можете попробовать очистить папку WTF и отключить остальные ваши дополнения для проверки этой функции. Если это имеет значение, вы можете включить их один раз, пока не найдете проблему.

...