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

Register forum user name Search FAQ

Gammon Forum

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  Lua
. . -> [Subject]  Upgrade from Lua 5.0.2 to Lua 5.1.1 in version 3.80 of MUSHclient

Upgrade from Lua 5.0.2 to Lua 5.1.1 in version 3.80 of MUSHclient

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page

Posted by Nick Gammon   Australia  (23,006 posts)  [Biography] bio   Forum Administrator
Date Fri 01 Sep 2006 06:38 AM (UTC)

Amended on Tue 14 Nov 2006 08:06 PM (UTC) by Nick Gammon

It is probably time to move from Lua 5.0 to Lua 5.1, now that Lua 5.1 has had time to settle down.

This document is an attempt to alert scripters to things to watch out for to make their scripts more easily changed over to Lua 5.1.

The improvements in Lua 5.1 over 5.0 are:

  • New module system making modular coding easier (see "require" and "module")

  • Incremental garbage collection

  • New "vararg" mechanism (ie. for functions that take a "..." argument)

  • New syntax for long strings (multiline strings and comments with [[ ... ]] around them)

  • Mod operator (%) for arithmetic and length operator (#) for strings and tables.

  • All data types can have metatables (in the C interface only however)

  • New function "string.match", which returns the first matched capture (like string.find but without the start and end position)

  • New function "string.reverse" that reverses its argument.

  • New function "load", which loads Lua code progressively by calling a function to concatenate together data.

  • New function "coroutine.running" which returns the currently-running coroutine, if any.

  • New function "math.modf" which returns the integral and fractional part of a number.

  • New maths functions sinh, cosh, and tanh for hyperbolic functions.

Generally speaking, most scripts should just continue to run without any problems. There are some areas which may require attention. I have found that the Lua chat module (itself pretty large) ran without changes under Lua 5.1.

Changes in the language syntax

  • Vararg system

    Functions that take a variable number of arguments no longer set up an "arg" table. Instead there is a new syntax "..." which can be used inside a function to represent the sequence of extra arguments.

    An example of its use is to take a variable number of arguments and pass them down to another function, like this:

    -- Lua 5.1 version
    function ferror (fmt, ...)
      error (string.format (fmt, ...), 2)
    end -- ferror

    In Lua 5.0 this would have been done this way:

    -- Lua 5.0 version
    function ferror (fmt, ...)
      error (string.format (fmt, unpack (arg)), 2)
    end -- ferror

    The new method basically saves having to create a temporary table (arg) and then unpack that back into a list of arguments, for cases like this where the arg table isn't really required.

    There is a new function "select" that lets you obtain the count of extra arguments, and also return a sequence from any position onwards. Thus you could make your "arg" table return by doing this:

    function f (...)
      local arg = {...}; arg.n = select ("#", ...)  --> emulate old behaviour
      print ("n =", arg.n)  --> count of args
      print (arg [1])       --> argument 1
      print (arg [2])       --> argument 2
    end -- f

  • Nested strings and comments

    In Lua 5.0 you could have multi-line strings, but they could not be nested (in other words you would have trouble making a string that had a multi-line string in it, and the same for multi-line comments.

    Now you can do this by using the [==[ ... ]==] syntax. This can be useful to comment out a block of code that already has comments in it, or make a multi-line string with comments in it.

    For example:

    a = [=[
      This is an example of code:
         b = [[ 
           a multi-line comment
           goes here ]]
    print (a)

    You can continue to nest such things by adding more "=" signs (eg. [====[ ... ]====] ). Each one is paired with its corresponding partner.

  • You can now use % as the modulus operator. eg.

    print (19 % 4)  --> 3

  • You can now use "#" as the length operator for tables and strings. eg.

    print (#"Nick Gammon") --> 11
    t = { 1, 2, 3 }
    print (#t) --> 3

  • Strings now have an automatic metatable containing "__index" which points to the string table.

    What this means is that these two techniques now have identical results:

    string.upper (s)

    and ...

    s:upper ()  --> where s is a string (note the colon, not a dot)

    For example:

    s = "nick"
    print (string.upper (s))  --> NICK
    print (s:upper ())        --> NICK

Changes in the libraries

  • The global function _TRACEBACK has been removed. Scripts that referred to that should now use debug.traceback.

  • New function "load". This calls a supplied function to gradually build up a Lua chunk. This could be useful for writing a preprocessor to read Lua code from a file and preprocess it before being compiled.

  • Function string.gfind was renamed string.gmatch. Now if you attempt to use string.gfind you will get this error message: 'string.gfind' was renamed to 'string.gmatch'

    To get the old behaviour back you could add this to the initialization part of your script:

    string.gfind = string.gmatch

    However it is probably just as easy to do a quick find-and-replace.

  • New function string.match - this is similar to string.find but doesn't return the indexes of the match, which can be more convenient.

    For example:

    print (string.find ("the quick brown fox", "(q%a+)")) --> 5 9 quick

    print (string.match ("the quick brown fox", "(q%a+)")) --> quick

    This would be handy where you don't care what the index numbers are.

  • When string.gsub is called with a function as its third argument, whenever this function returns nil or false the replacement string is the whole match, instead of the empty string.

    This is useful because of this sort of case:

    replacements = { 
       ["nice"] = "windy",
       ["walk"] = "stroll",
    s = "a nice long walk"
    result = string.gsub (s, "%a+", 
      function (str)
      return replacements [str]   --> **** see below ****

    Previously under Lua 5.0 the marked line would have read:

     return replacements [str] or str

    It seems unlikely that you want to have nil become an empty string, so this behaviour is more natural. If you want the empty string you can simply return an empty string.

  • string.gsub can now be called with a table as its third argument, in which case matching items in the string are replaced by doing a table lookup. Thus the above example could be rewritten as:

    s = "a nice long walk"

    result = string.gsub (s, "%a+", 
       ["nice"] = "windy",
       ["walk"] = "stroll",

    This is even simpler then having to write a function, if simple replacement of one string by another is all that is required.

  • Function table.setn was removed.

    Attempts to set the length of a table with table.setn will now fail with the error message: 'setn' is obsolete

    In the past table.setn was supposed to let you make numerically-indexed tables with gaps (ie. nil values) in the middle. They seem to have decided not to encourage this behaviour.

  • Function table.getn corresponds to the new length operator (#); use the operator instead of the function.

    You can now get the length of a table (or a string) with the # operator. For example:

    t = {"nice", "day", "for", "a", "walk"}
    print (#t)  --> 5

  • There is a new function "table.maxn" that finds the maximum numeric entry, in case you have a table with holes in it. eg.

    t = {[1] = "hi", [10] = "there"}
    print ("n = ", #t)  --> n =  1
    print ("maxn = ", table.maxn (t)) --> maxn =  10

    Be warned that this function simply does a linear scan of every item in the table. It simply finds the largest key which is a number.

  • Function loadlib was renamed package.loadlib.

    If you want the old behaviour back you would need to do this:

    loadlib = package.loadlib

  • Function math.mod was renamed math.fmod.

    If you attempt to use math.mod it will be nil. You can either reword it as math.fmod or use the new % (modulus) operator.

  • Functions table.foreach and table.foreachi are deprecated. You can use a for loop with pairs or ipairs instead.

    They may be deprecated however they still work. You are advised to rework loops as advised in case they are removed from future versions. eg. Instead of:

    table.foreach (t, print)


    for k, v in pairs (t) do
      print (k, v)
    end -- for

  • The syntax "for k, v in t do" where t is a table is deprecated and no longer works. Use pairs (t) instead (as in example above).

  • There were substantial changes in function 'require' due to the new module system. However, the new behavior is mostly compatible with the old, but 'require' gets the path from package.path instead of from LUA_PATH.

    The new module system attempts to simplify loading multiple modules, in a more powerful way than the old "requires" function. Just as an example to see what it is doing, try doing this:

    require "blah"
    module 'blah' not found:
            no field package.preload['blah']
            no file '.\blah.lua'
            no file 'C:\MUSHclient\lua\blah.lua'
            no file 'C:\MUSHclient\lua\blah\init.lua'
            no file 'C:\MUSHclient\blah.lua'
            no file 'C:\MUSHclient\blah\init.lua'
            no file '.\blah.dll'
            no file 'C:\MUSHclient\blah.dll'
            no file 'C:\MUSHclient\loadall.dll'

    Basically what it is doing is to try to locate your module "blah" by substituting it repeatedly into this string and trying to open the appropriate file:


    The character "!" represents "the path to the executable", which is why it is "C:\MUSHclient\" in my example.

    If it cannot find the .lua file it tries to find a .dll file by substitution in this string:


    In the case of a DLL it then attempts to find an entry point named "luaopen_?" where ? is the module name (eg. loaopen_blah in my example).

    There is more to it than that, read the reference manual for more information.

  • Function collectgarbage has different arguments.

    This function is a generic interface to the garbage collector. It performs different functions according to its first argument, opt:

    • "stop": stops the garbage collector.
    • "restart": restarts the garbage collector.
    • "collect": performs a full garbage-collection cycle.
    • "count": returns the total memory in use by Lua (in Kbytes).
    • "step": performs a garbage-collection step. The step "size" is controlled by arg (larger values mean more steps) in a non-specified way. If you want to control the step size you must experimentally tune the value of arg. Returns true if the step finished a collection cycle.
    • "setpause": sets arg/100 as the new value for the pause of the collector.
    • "setstepmul": sets arg/100 as the new value for the step multiplier of the collector.

  • Function gcinfo is deprecated; use collectgarbage("count") instead.

  • Numeric conversion in string.format now works for larger numbers. Previously doing this had a practical limit of 30-bit numbers:

    print (string.format ("%d", 2^30)) --> 1073741824
    print (string.format ("%d", 2^31)) --> -2147483648

    Clearly the second answer is incorrect because internally a 32-bit number has wrapped around and become negative.

    In the new version this is achieved with 64-bit numbers so we can now go up to 2^62, like this:

    print (string.format ("%d", 2^62)) --> 4611686018427387904
    print (string.format ("%d", 2^63)) --> -9223372036854775808

  • The function coroutine.status now returns another value, namely "normal" under certain circumstances.

Changes in the API

These affect C programmers who are writing their own Lua modules. I won't go into all of them here, see the reference manual.

- Nick Gammon

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

Posted by Nick Gammon   Australia  (23,006 posts)  [Biography] bio   Forum Administrator
Date Reply #1 on Fri 01 Sep 2006 07:17 AM (UTC)
Incompatibilities with existing DLLs

Unfortunately, because of the internal changes, you simply cannot use Lua 5.1 with the same DLLs that run with Lua 5.0. This is one of the reasons I wasn't in a big hurry to change to Lua 5.1.

If you write your own libraries, the changes are pretty simple:

  • Link against lua5.1.lib rather than lua50.lib:

    #pragma comment( lib, "lua5.1.lib" )

    I will supply a copy of that file with the MUSHclient release.

  • Change the one place where you register the routines in your DLL from using luaL_openlib to luaL_register, like this ...


      luaL_openlib(L, "mystuff", mystuff, 0);


      luaL_register(L, "mystuff", mystuff);

Don't be tempted to try to run with both versions of Lua by keeping a copy of Lua 5.0.2 DLL hanging around. MUSHclient will crash, I can assure you, as the two versions of Lua fight it out about what their internal structures mean.

So far I have successfully recompiled the luasql library from the source and connected to a database OK.

I am still wrestling with the luasocket library, and have yet to tackle luacom.

I had hoped that the developers of those libraries would have released versions compatible with Lua 5.1 by now, but it seems not.

I will continue to investigate these issues, so that by the time the new version is released I can be reasonably sure that most users will not have major problems.

- Nick Gammon

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

Posted by Nick Gammon   Australia  (23,006 posts)  [Biography] bio   Forum Administrator
Date Reply #2 on Sat 02 Sep 2006 12:25 AM (UTC)

Amended on Sat 01 Dec 2007 07:25 PM (UTC) by Nick Gammon

How to get LuaSocket to work

See the end of this post for amended instructions (December 2007)

This was a bit counterintuitive, so I will document what I did here.

I downloaded the file:


from a link on:


Inside are two directories:

  • lua
  • lib

Extract the "lua" directory into the directory where the MUSHclient executable is. This contains:

  • ltn12.lua
  • mime.lua
  • socket.lua
  • mime (empty directory)
  • socket - directory containing:

    • ftp.lua
    • http.lua
    • smtp.lua
    • tp.lua
    • url.lua

Now, move the mime and socket directory out of the lua directory to be at the same level as the lua directory.

Next, move the file core.dll from the directory lib\socket into the socket directory.

Then, move the file core.dll from the directory mime\socket into the mime directory.

Now it should work. I tried this:

http = require "socket.http" 
a, b, c = http.request("http://some.web.site/")
print (a, b, c)  -- page, return code, headers

My final structure was:

MUSHclient directory

MUSHclient.exe ... and other related files ...
mime (dir)
socket (dir)
lua (dir)

mime directory

core.dll (the one from the lib\mime directory initially)

socket directory

core.dll (the one from the lib\socket directory initially)

lua directory



See http://www.gammon.com.au/forum/?id=8319 for amended instructions (December 2007) as the file described above is no longer there. This post describes a simpler way of getting LuaSocket to work.

- Nick Gammon

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

Posted by Nick Gammon   Australia  (23,006 posts)  [Biography] bio   Forum Administrator
Date Reply #3 on Sat 02 Sep 2006 03:18 AM (UTC)
Getting LuaCom to work

This was trickier because I could not find a precompiled binary for it.

After a considerable amount of mucking around I got the source for Luacom 1.3 compiled into a DLL. This test code now works:

-- load luacom
assert (package.loadlib ("luacom.dll","luacom_open")) ()

-- Instantiate a Microsoft(R) Calendar Object
calendar = luacom.CreateObject("MSCAL.Calendar")

-- Error check
if calendar == nil then
  error ("Error creating object")

-- Method call

-- Property Get
current_day = calendar.Day

-- Property Put
calendar.Month = calendar.Month + 1


I will make a copy of luacom.dll available for people wanting to use COM with Lua 5.1.

- Nick Gammon

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

Posted by Nick Gammon   Australia  (23,006 posts)  [Biography] bio   Forum Administrator
Date Reply #4 on Sat 02 Sep 2006 11:45 PM (UTC)
I now also have working versions (or they seem to work anyway) of the odbc.dll and mysql.dll for use with Lua 5.1, so that database queries are still available.

I will make all these DLLs available as optional extras when version 3.80 of MUSHclient is released.

- Nick Gammon

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

Posted by Nick Gammon   Australia  (23,006 posts)  [Biography] bio   Forum Administrator
Date Reply #5 on Mon 04 Sep 2006 09:55 PM (UTC)
See this post for a discussion about the issue of the loadlib function being moved from the base library to the package library:


- Nick Gammon

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

Posted by Nick Gammon   Australia  (23,006 posts)  [Biography] bio   Forum Administrator
Date Reply #6 on Fri 08 Sep 2006 07:50 PM (UTC)

Amended on Sat 01 Dec 2007 07:24 PM (UTC) by Nick Gammon


Upgraded DLLs for use with Lua 5.1

Various DLLs have been recompiled for use with MUSHclient 3.80. These are in the directory http://www.gammon.com.au/files/mushclient/lua5.1_extras/.

  • G15_Display.zip - DLL for use with the Logitech G15 gamers keyboard (45 Kb)
  • lua5.1.zip - Standalone version of Lua 5.1 (lua5.1.exe) and the DLL required to run it (lua5.1.dll). The DLL itself ships with the MUSHclient download. (129 Kb)
  • lua5.1_lib.zip - lua5.1.lib for linking against your own DLLs that you write, plus the Lua 5.1 include files (luaconf.h, lua.h, lauxlib.h and lualib.h) which are needed for writing them. Only download this if you are planning to write your own DLLs. (17 Kb)
  • luac5.1.zip - Lua 5.1 compiler (stand-alone program) called luac5.1.exe. You only need this if you want to make Lua "object" files. (102 Kb)
  • luacom.zip - Lua COM package compiled to run with Lua 5.1 (eg. for loading in the speech synthesizer). (90 Kb)
  • mysql.zip - Lua SQL package for use with MySQL databases, compiled to run with Lua 5.1. (27 Kb)
  • odbc.zip - Lua SQL package for use with ODBC databases, compiled to run with Lua 5.1. (27 Kb)
  • windows_utils.zip - a couple of utilities, for bringing programs to the front, and executing shell commands. (27 Kb)
  • luasocket-2.0.1.zip - the DLLs and Lua files to make LuaSocket work, as described above. (35 Kb)

MD5 sums for the above files:

fa6515b07b043812d77c9b9dc0ce3f53 G15_Display.zip
cfbdf64ed0fd5c228a9df9eeaea96767 lua5.1.zip
2d6e852f332db06978ffa57d56817b00 lua5.1_lib.zip
1342cf83842ddf244ce267df23d63a29 luac5.1.zip
02f70e7e108ebdb7e7276cef27a295ac luacom.zip
3a5d1c196819d957578f77231070153e mysql.zip
7ebf3323439afe75d47f565c3a477d0e odbc.zip
f50a017e6fcbb3a5489623ea9ad4c989 windows_utils.zip
7ebacf720d7113a0b261c5e4e315a8c6 luasocket-2.0.1.zip

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[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.


It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page

Go to topic:           Search the forum

[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

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

[Best viewed with any browser - 2K]    [Hosted at HostDash]