[Home] [Downloads] [Search] [Help/forum]

Gammon Software Solutions forum

See www.mushclient.com/spam for dealing with forum spam. Please read the MUSHclient FAQ!

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  Lua
. . -> [Subject]  help with nil results and metatables

Home  |  Users  |  Search  |  FAQ
Username:
Register forum user name
Password:
Forgotten password?
(New message)
Subject: help with nil results and metatables
Name:
Your forum user name.
Register forum user name
Password:
Your forum password.
Forgotten password?
Message:
Message to be posted (in English, please).
Forum codes:
Check this if your message uses 'forum codes' or templates (auto-detected for new posts).
Forum codes Templates

Save this message ...


Subject review (reverse sequence)

Posted by Fiendish   USA  (849 posts)  [Biography] bio   Global Moderator
Date Fri 03 Aug 2012 04:03 PM (UTC)  quote  ]
Message
Though, now that you are sanely checking for the spell's existence in memt, perhaps you no longer need Nick's patch because you should have already set up .mem elsewhere?

http://aardwolfclientpackage.googlecode.com/
[Go to top] top

Posted by Fiendish   USA  (849 posts)  [Biography] bio   Global Moderator
Date Fri 03 Aug 2012 12:23 PM (UTC)  quote  ]
Message
for s,m in pairs(memt) do
    if s == spell_cast then
    ...
end


Can be done much more simply with just

if memt[spell_cast] then
   ...
end

http://aardwolfclientpackage.googlecode.com/
[Go to top] top

Posted by Hoplo   (16 posts)  [Biography] bio
Date Fri 03 Aug 2012 04:07 AM (UTC)  quote  ]
Message

function docasted(name, line, wildcards)
 spell_cast = wildcards [1]
 memc = 0;

 if spell_cast == "heal" then
  healc = tonumber (GetVariable("healcount")) - 1
  Note (" *** ".. healc .." of Heal left ***")
    if healc <= 3 then
      if healc == 1 then
       Send("gt *** ".. healc .." HEAL REMAINING ***")
      else
       Send("gt *** ".. healc .." HEALS REMAINING ***")
      end
    end
 else
  for s,m in pairs(memt) do
    if s == spell_cast then
      memt [spell_cast].mem = (memt [spell_cast].mem or 0) - 1
      memc = memt [spell_cast].mem
      Note (" *** ".. memc .." of " .. spell_cast .." left ***")
    end -- if
  end -- for
 end -- if
end -- function


This fixed my problem. Thanks for the help.
[Go to top] top

Posted by Fiendish   USA  (849 posts)  [Biography] bio   Global Moderator
Date Thu 02 Aug 2012 10:05 PM (UTC)  quote  ]

Amended on Thu 02 Aug 2012 10:09 PM (UTC) by Fiendish

Message
Hoplo said:
However, the memt table is populated by "meaningful members" that work just fine.
No it is not. Not when the spell isn't already in the table.

Quote:
Then, I believe, the issue is not simple ensuring there is a .mem to subract, but the whole parent subtable of the spell name the .mem is applied to exists.

The error message you posted does not support your belief.

Here's the thing. Your metatable trick worked. It's a silly thing to do because it clearly solves only half of your original problem (you tried to access a member of nil), and does so in a way you don't understand, but it did work. memt[spell_cast] will no longer return nil.
Much more sane would have been to check if memt[spell_cast] is null and create a new table on that condition with the appropriate mem value. Or better yet, not a table at all. Tables containing a single member are silly. You might as well just make memt[spell_cast] store the value mem directly.
But now you have just punted your nil problem down the field. memt[spell_cast] no longer returns nil, it returns an empty table. Your problem now is that empty tables are empty. They do not contain mem. So trying to access .mem returns nil. This is only a problem when you try to subtract 1.

Quote:
I did try Nick's suggestion, with the same error being returned.
I doubt that. What Nick posted would solve the error you showed given the code you showed. Please post your new code and new error message.

http://aardwolfclientpackage.googlecode.com/
[Go to top] top

Posted by Hoplo   (16 posts)  [Biography] bio
Date Thu 02 Aug 2012 09:24 PM (UTC)  quote  ]

Amended on Fri 03 Aug 2012 03:28 AM (UTC) by Hoplo

Message
"construct a member table for memt[spell_cast], you neglect to give it any meaningful members. The problem is your arithmetic, not your table. That is, you have no ".mem" from which to subtract 1."

I will freely admit I have little idea of what I am doing, as I tried to state above. I am aware the issue is an arithmetic problem because there is not a number in certain ".mem"s to subtract from.

However, the memt table is populated by "meaningful members" that work just fine. The problem I posted is when a spell is cast that is not in the table. Then, I believe, the issue is not simple ensuring there is a .mem to subract, but the whole parent subtable of the spell name the .mem is applied to exists.

I did try Nick's suggestion, with the same error being returned.

If it may help, the when I use tprint (memt) I get something like :
"blindness":
"mem"="4"
"silence":
"mem"="2"

"the thing you did wrong was trying to write a solution before understanding the problem."

I tried what I thought might work. I certainly would not be surprised if I was wrong.
[Go to top] top

Posted by Fiendish   USA  (849 posts)  [Biography] bio   Global Moderator
Date Thu 02 Aug 2012 08:09 PM (UTC)  quote  ]

Amended on Sat 04 Aug 2012 04:38 PM (UTC) by Fiendish

Message
Hoplo said:

Thank you Nick, I am sure I will need this once the first step is fixed.

There is no first step. Nick understands the problem I am talking about.


Quote:
The problem, as Fiendish has noted, is that the error starts when a spell not in the table is attempted.

No. The problem happens because, while you construct a member table for memt[spell_cast], you neglect to give it any meaningful members. The problem is your arithmetic, not your table. That is, you have no ".mem" from which to subtract 1.

Quote:
...stuff...I had attemted something like this in the original code post, but I have done something obviously wrong.

IMO, the thing you did wrong was trying to write a solution before understanding the problem. Checking the existence of something before using it is trivial and does not become easier with metatables.

http://aardwolfclientpackage.googlecode.com/
[Go to top] top

Posted by Hoplo   (16 posts)  [Biography] bio
Date Thu 02 Aug 2012 05:59 PM (UTC)  quote  ]
Message
Thank you Nick, I am sure I will need this once the first step is fixed. The problem, as Fiendish has noted, is that the error starts when a spell not in the table is attempted. The table is formed automatically from a list of memorized spells provided from the mud.

What I would ultimately like to do is make it so if a spell is attempted that is not in the list then there is not an error.

One way to do this would be to simply have the script do something like a ipair search through the table to see if the spell is there and then cast it, or exit the script. This can cause a problem because there are unique situations where spells can be cast even if they are not memorized ( as seen by my hackish "heal" check). But, I am not really sure how to do this... I will give it a try.

Another way that sounded promising was to use a metatable to make the entry as needed. Again, I am not really sure how to do this either. I had attemted something like this in the original code post, but I have done something obviously wrong.
[Go to top] top

Posted by Nick Gammon   Australia  (18,772 posts)  [Biography] bio   Forum Administrator
Date Thu 02 Aug 2012 05:53 AM (UTC)  quote  ]
Message

 memt [spell_cast].mem = memt [spell_cast].mem - 1


If there is doubt if mem exists, you can do this:


 memt [spell_cast].mem = (memt [spell_cast].mem or 0) - 1

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Fiendish   USA  (849 posts)  [Biography] bio   Global Moderator
Date Thu 02 Aug 2012 04:28 AM (UTC)  quote  ]
Message
I already told you what the problem is.

http://aardwolfclientpackage.googlecode.com/
[Go to top] top

Posted by Hoplo   (16 posts)  [Biography] bio
Date Thu 02 Aug 2012 01:32 AM (UTC)  quote  ]
Message
Sorry for the late response, was working on other things. I updated the script a bit and made it into a function.


function docasted(name, line, wildcards)
 spell_cast = wildcards [1]
 setmetatable (memt, { __index = function () return {} end } )
 memc = 0; 

 if spell_cast == "heal" then
  healc = tonumber (GetVariable("healcount")) - 1
  Note (" *** ".. healc .." of Heal left ***")
    if healc <= 3 then
      if healc == 1 then
       Send("gt *** ".. healc .." HEAL REMAINING ***")
      else
       Send("gt *** ".. healc .." HEALS REMAINING ***")
      end
    end
 else
   memt [spell_cast].mem = memt [spell_cast].mem - 1
   memc = memt [spell_cast].mem
   Note (" *** ".. memc .." of " .. spell_cast .." left ***")
 end -- if
end -- function


the error i get is :

You utter the words, 'ewd exe'
Run-time error
World: BaseArctic
Function/Sub: docasted called by trigger
Reason: processing trigger ""
[string "Script file"]:42: attempt to perform arithmetic on field 'mem' (a nil value)
stack traceback:
[string "Script file"]:42: in function <[string "Script file"]:26>
Error context in script:
38 : Send("gt *** ".. healc .." HEALS REMAINING ***")
39 : end
40 : end
41 : else
42*: memt [spell_cast].mem = memt [spell_cast].mem - 1
43 : memc = memt [spell_cast].mem
44 : Note (" *** ".. memc .." of " .. spell_cast .." left ***")
45 : end -- if
46 : end -- function
You've never heard of such a spell.

I tried to add in a meta table as shown in here.
http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=9085




[Go to top] top

Posted by Fiendish   USA  (849 posts)  [Biography] bio   Global Moderator
Date Tue 31 Jul 2012 11:34 PM (UTC)  quote  ]

Amended on Tue 31 Jul 2012 11:35 PM (UTC) by Fiendish

Message
Quote:
If the spell is not then I get a Nil error.

Of course you do. If memt[spell_cast] doesn't exist it gets set to {}. {}.mem results in nil. You then try to subtract 1 from nil.

In the future post your actual error message. We all know that MUSHclient gave you something far more specific and useful than just "a Nil error". So please next time actually tell us what it is.

http://aardwolfclientpackage.googlecode.com/
[Go to top] top

Posted by Nick Gammon   Australia  (18,772 posts)  [Biography] bio   Forum Administrator
Date Tue 31 Jul 2012 10:42 PM (UTC)  quote  ]
Message
What other thread?

Template:codetag To make your code more readable please use [code] tags as described here.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Hoplo   (16 posts)  [Biography] bio
Date Tue 31 Jul 2012 08:55 AM (UTC)  quote  ]
Message
I have seen an example of how this is supposed to work (i think), but I seem to be doing something wrong.

the goal is have a trigger that decreases the number of spells memorized as i cast them.
This is what I have so far:

<triggers>
<trigger
enabled="y"
expand_variables="y"
group="spellcounter"
match="^You utter the words\, \'([a-zA-Z ]+)\'$"
regexp="y"
send_to="12"
sequence="100"
>
<send>
spell_cast = "%1"
memc = 0;

memt [spell_cast] = memt [spell_cast] or {}

mt = { __index =
function (tbl, key)
tbl [key] = {} -- add sub table
return tbl [key] -- return as missing value
end }

setmetatable (memt, mt)

memt [spell_cast].mem = memt [spell_cast].mem - 1
memc = memt [spell_cast].mem

Note (" *** ".. memc .." of " .. spell_cast .." left ***")
end</send>
</trigger>
</triggers>

Everything works as long as the spell is in the table. If the spell is not then I get a Nil error. The memt table is already set and populated through another trigger based on information from the mud; however, sometimes a character is able to cast a spell even if it is not memorized.

I tried to use a metatable as shown in another thread, but I do not seem to have it working right because I still get the error.
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


1,310 views.

[Reply to this subject]  Reply to this subject   [New subject]  Start a new subject   [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

[Home]

Written by Nick Gammon - 5K

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( http://www.gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Internet Contents Rating Association (ICRA) - 2K]    [Web site powered by FutureQuest.Net]