Lua and Corona SDK language (3/3 part)

@
Show original
image final thirds of part of a big review on language Lua in Corona SDK will be considered by

B of this very important questions after which studying you will be able directly to pass to Corona SDK studying.

  • Cyclic operations
  • Work with files
  • Date and time
  • Function
  • Regular expressions and captures
  • Management of accident
  • Mathematical functions
  • Careful attitude to the stranger

is possible someone I did not read the first two parts of this article to them I advise to begin with their reading: the first part and the second part

Cyclic operations


B any language and almost for any task surely will arise a situation at which some site of a code needs to be executed several times. For this task cyclic operations are used. In the Lua language there are 2 operators allowing to organize cycles (for and while ), further I will describe them.

of while (exp) do end

the Code between do and end is carried out by
until then while result of expression of exp — truth (true ). I will give an example of realization of a cycle: = 4 - number of repetitions of local b = true - an exit flag from the cycle local i = 0 - we create

  of local count and we nullify the while b do counter - the cycle is carried out while b is equal to true i = to i %2B 1 - we increase the print (i) counter - the press of the current value of the if i counter> = count then - if the counter reached b = false - we put an exit flag from the cycle end end->> 1->> 2->> 3->> 4  
we to a cycle establish to Variable b
true value and further after achievement of the necessary condition of the counter we put b equal false and there is an exit from a cycle. There is a way of creation of a cycle in while true do end the eternal cycle thus is created — it is rather dangerous situation and always it is necessary to have steady conditions of an exit from such cycles, in Lua for these purposes there is an operator of break — this operator certainly finishes cycle performance. Let's review an example: = 4 - number of repetitions of local i = 0 - we create

  of local count and we nullify the while true do counter - an eternal cycle i = i %2B 1 - we increase the print (i) counter - the press of the current value of the if i counter> = count then - if the counter reached break - an exit from the cycle end end->> 1->> 2->> 3->> 4  

do not allow negligence at the organization of eternal cycles and as a whole when using while. Not always it is possible to foretell precisely that in any situation the cycle will be complete, and it leads to deep lag of the appendix.

of for (exp) do end

the Code located between do and end will carry out
according to rules established in exp. The cycle for has a wide circulation among a programming language, in Lua this operator it is possible to apply in two ways, below we will consider them. The first and simplest way will be easily clear to any user familiar with any programming language:

  of for i = 1,3 do - a cycle is carried out 3 times as increase in print (i) end->> 1->> 2->> 3  

In certain cases need to increase an iterator not by unit, and for example on 2 or 5 as the option at which you want to consider in the opposite direction is possible. It is realized use 3 for parameters which determines increment size for one step. - we consider

  from 2 to 6 adding on 2 for i = 2,6,2 do print (i) of end->> 2->> 4->> 6 - we consider from 9 to 3 taking away on 3 for i = 9,3,-3 do print (i) of end->> 9->> 6->> 3  

This option of the cycle for was already considered by

of for [values] in (func) of do end


Literally in the following section by work consideration with files you we will consider one more option of cyclic function as argument of a cycle — file:lines .

Work with files


For work with files in Corona SDK is used standard library of input-output of Lua — io. Not all functions of library have cross-platform realization as not all functions in Corona SDK are realized just as it is accepted in Lua. Along with work with files the io library in Lua can be used for work with the console ( if not to specify a file ), but in Corona SDK this action will happen not absolutely truly, I will give an example:

  of io.write ('A: ') local A = io.read () io.write ('B: ') local B = io.read () io.write ('A %2B B =', A %2B B, '%5Cn')  

Is the code fragment in Lua works so: the first line in the console is carried out the line "is removed by A: ", further it is expected while the user will enter number and will press Enter, further the same operation takes place from a variable B then there is a conclusion of result of summation. In Corona SDK there is no performance stop on the second and fourth line, and as a result there is a mistake on the 5th line in attempt to put 2 variable equal nil. I.e. the application creation accepting parameters from the console in Corona SDK is not possible, i.e. for work with the console it is necessary to use only io.write for a text conclusion, but this function has a direct analog — print. From above told it is worth drawing a conclusion that for work with the console is not present sense to use io . With files the library suits for work, but besides because of doubtful realization in Corona SDK it is better to use library in the most obvious and simple way: "Opened/created — Read — Wrote down — Closed". As when developing in Corona SDK it is necessary to consider that special system of catalogs peculiar to mobile applications, we and will begin with it.

Catalogues available to the appendix


All these appendices are in the appendix isolated from others space, there are some catalogs:

  • the Main catalog (system.ResourceDirectory) — is the catalog by default, it corresponds to the catalog of placement of the main.lua file. Record in this catalog is not available, it is possible to read only.
  • the Catalogue of documents (system.DocumentsDirectory) — can store settings of the user in this catalog and other files which the application creates at installation and further it should not delete. This catalog is available both to record and for reading and data in it will be removed only during removal of the appendix. In Apple iOS this catalog is used in system of synchronization of these appendices, i.e. the user will receive the settings for your appendix on other device if synchronizes settings.
  • the Temporary catalog (system.TemporaryDirectory) — in this catalog need to create files demanded in a frame of one session if to finish the appendix, the operating system reserves the right to remove these files. Do not place files of settings in this catalog. It is available to record and for reading.
  • the Additional catalog (system.CachesDirectory) — this catalog has longer cycle of data storage, but nevertheless for important information you should not use it. In Apple iOS this catalog is not used in system of synchronization of these appendices i.e. if you purposefully want to avoid that your players could not synchronize control between various devices, can store data in this catalog. It is available to record and for reading.
by
During the work with files it is used functions of opening of the file they the indication of a way to the file demand, the way consists of a directory and a file name, for formation of correct value of a way of the file in Corona SDK the system.pathForFile function is used, the funktsuiya is applied as follows:

  of local fileName = 'saves.dat' local filePath = system.pathForFile (fileName, system.DocumentsDirectory)  

as the second parameter it is necessary to use one of available values: system.ResourceDirectory, system.DocumentsDirectory, system.TemporaryDirectory, system.CachesDirectory . As already value by default for system.ResourceDirectory was told above i.e. if not to specify the second parameter by a root of a way will consider the catalog with the main.lua file.

Many functions in Corona SDK I use files for the work, for example display.newImage loads the image from the file on the device screen in these functions a name of the file is entered separately from the catalog:

  of local mouse = display.newImage ("assets/images/mouse.png", system. ResourceDirectory, 0, 0)  

As system. ResourceDirectory — value by default, this parameter it is possible not to enter, having reduced thereby record:

  of local mouse = display.newImage ("assets/images/mouse.png", 0, 0)  

Pay attention to 3 things:

  • to a name of the file can be added and catalogs
  • the beginning of a way does not contain a slash "/"
  • in a way the direct slash /" is used ", ( as in the browser or UNIX systems ), it is possible to use in a way "the return slash %5C" (as in Windows) but this symbol is shielding and if strongly there is a wish to apply it use a double symbol" %5C%5C" as actually it will be perceived as unary
by
IMPORTANT : At which the appendix works as one of the most popular causes of error at a computer simulator, but does not work at the device, application of various register in names of catalogs and files is. The matter is that in a simulator there is no dependence on the register, i.e. Assets/Images/Mouse.PNG and assets/images/mouse.png — is considered the same way, in Google Android and Apple iOS are different ways, t.o. if in function the way in the bottom register is specified, and really names of catalogs or files have symbols of the top register ( or on the contrary ) — it leads to a mistake. Try everywhere and to avoid always names of catalogs and files with symbols of the top register.

Further we will consider the simplest and acceptable working methods with files. In this lesson I not will write the variant of translation of official reference materials them you can read as for Lua and for crowns , I will try to give out you the most necessary namely how to make convenient storage of settings of the project and to realize work with ravines.

Creation/record/reading the file entirely


we Realize a simple example in which the file is created and in it the line registers:

  of local write_data = "Hello file!" - line for local fileName file recording = 'saves.dat' - a local filePath file name = system.pathForFile (fileName, system.DocumentsDirectory) - a way to the local file file = io.open (filePath, "w") - we open the file with its creation for the record file:write (write_data) - we write down io.close(file) - we close the file  

we Will consider features. As io.open as the second parameter the special flag which defines type of access to the file is used, we will consider the main flags of access:

  • of "r" — a reading mode (by default); the index of the file is located at the beginning of the file
  • with "w"
  • — a mode only for record; rewrites the file if the file exists. If the file does not exist, the new file for record is created.
  • "a"
  • — an addition mode (only for record); the index of the file is in the file end if the file exists (the file is in an addition mode). If the file does not exist, it creates the new file for record.
  • "r%2B"
  • — a mode of updating (reading / record); all previous data are kept. The index of the file will be at the beginning of the file. If the file exists, it will be rewritten, only if you obviously write to it.
  • "w%2B"
  • — a mode of updating (reading / record); all previous data are erased. Rewrites the existing file if the file exists. If the file does not exist, the new file for reading and record is created.
  • "a%2B"
  • — to add a mode of updating (reading / record); the previous data remain, and record is allowed only at the end of the file. The index of the file is in the file end if the file exists (the file opens in an addition mode). If the file does not exist, it creates the new file for reading and record.

we Realize an example of opening of the file and reading from it all contents ( of a line written down last time ):

  of local fileName = 'saves.dat' - a local filePath file name = system.pathForFile (fileName, system.DocumentsDirectory) - a way to the local file file = io.open (filePath, "r") - we open the file for reading local read_data = file:read ("*a") - all io.close (file) file is readable - we close the print (read_data)  

IMPORTANT : If you want working to see in the emulator files created in catalogs of the project it is necessary to execute action: File-> Show Project Sandbox, thus will open the root catalog of the project (system.ResourceDirectory), in this folder you will find three enclosed folders:

  • of CachedFiles — system.CachesDirectory
  • Documents — system.DocumentsDirectory TemporaryFiles — system.TemporaryDirectory

the mode of work Considered above with files each time rewrites the file at record and all file entirely is read that can be useful if you want to store in the file of control of your game, but this method has one essential shortcoming — for preservation of their settings it is necessary to format somehow and that further when opening for reading it would be possible to read back them if you have not many settings and there are no nested tables, that most likely special problems will not arise ( but it all the same is not convenient ) if the structure of your settings rather difficult is more convenient to use the json format ( the reference for those who does not know about what the speech, but wants to learn ) as the instrument of serialization. The sequence of our actions will be such:

  • All settings of the project is stored the table config
  • Before file recording we translate config contents in json
  • Is written down in the file
  • For reading settings we open the file is read out all contents of the file in the string
  • to
  • Is transferred from json to the table
  • we Initialize config

I will give an example of the simple project which realizes the idea described above Below, you will be able easily to transfer this mechanism to the projects as for this occupation the universal library in which it is required to you for adaptation to the project only to fill a template of settings by default, well and at desire to change a name of the file of settings was made.

the Code of library (libLoadSave.lua) of

 ------------------------------------------Library for work with settings------------------------------------------local M = { template = { - a template of settings - values by default num = 1, - number of starts of time = 0, - time of the last start }, config_file = system.pathForFile ('saves.dat', system.DocumentsDirectory) - a way to the file } local json = require "json" - we connect to the project json library - preservation of settings for a disk, - if the file is not present - creation of the sample M.save settings = function () local file = io.open (M.config_file, "w") - we open the file for the record if file then - if opening took place successfully local write_data = json.encode(config) - we transfer settings to json file:write (write_data) - io.close(file) file recording - end end file closing - loading of settings from the M.load file = to function () local file = io.open (M.config_file, "r") - file opening for reading - if the file exists if file then local read_data = file:read ("*a") - we read the file entirely config = to json.decode (read_data) - we transfer from json to lua, we initialize config io.close (file) - if the file is not present else config = M.template - we equate settings to the M.save template () - we create the file with the sample end end return M  

the Order of application of library the following:

  • to Create global config
  • to Connect to the project library
  • to Cause at the beginning of a code loading of settings
  • If settings were changed and they need to be kept we cause function of preservation

we Will consider a source code of the main file realizing the described mechanism:

  - main.lua config = { } - storage of settings (the global variable - is visible in all project) ls = require "libLoadSave" - we connect a biblioyetka of ls.load () - we load settings - we remove current state of the settings for k, v in pairs (config) of do print (string.format (' %s = %d', k, v)) end - we change the config.num settings = config.num %2B 1 - we increase number of starts of config.time = os.time () - time poslednengo ls.save start () - we keep  

Creation/record/reading the file postrochno


we Will consider work option with files at which the following sequence of actions will be performed:

  • If is not present the file — we create — we write down a line
  • If the file is we finish a line in the file

 of local write_data = "Very important entry in the log%5Cn" - a line for local fileName file recording = 'log.txt' - a local filePath file name = system.pathForFile (fileName, system.CachesDirectory) - a way to the local file file = io.open (filePath, "a") - we open the file, we put the index in the file end if the file is not present - we create file:write (write_data) - we write down io.close(file) - we close the file  

As we review this example intending in the subsequent to realize the log of the project, pay attention to that that the file I store in the catalog kesha as it is possible to store it in a temporary directory. It is connected with that that the ravine have the greatest value as hardware dependent data, for example on one device you have a mistake and on other is not present, and synchronization of dens in the general order will badly affect their informational content. Storage of dens in the temporary folder gives the chance to avoid essential drift of the size taken by the appendix ( if to store the ravine for years ) as at each reset of the appendix the ravine will be removed ( it not always so, more often the ravine are removed at restart of phone or as a result of work of everyones "chistilok" ).

the Second step of realization of dens will be consideration of a way of line-by-line reading the file — it is useful for data reading from the ravine:

  of local fileName = 'log.txt' - a local filePath file name = system.pathForFile (fileName, system.CachesDirectory) - a way to the local file file = io.open (filePath, "r") - we open the file for reading for line in file:lines () do - in a cycle we read all lines print (line) - the press of a line in the end io.close console (file) - we close the file  

Now as well as last time we realize convenient for transfer and a reuse the mechanism of dens. At first code of library (libLog.lua):

 ------------------------------------Library for work with the ravine------------------------------------local M = { log_file = system.pathForFile ('log.txt', system.CachesDirectory) - a way to the file } - record to M.write ravine = function(msg) local file = io.open (M.log_file, "a") - we open the file for record in if file then end - if opening took place successfully local dt = os.date ("%x %X") - local write_str date time = string.format (' %s %q%5Cn', dt, msg) file:write (write_str) - io.close(file) file recording - end end file closing - the ravine press in the M.read console = function () local file = io.open (M.log_file, "r") - file opening for reading - if the file exists if file then for line in file:lines () do - in a cycle we read all lines print (line) - the press of a line in the end io.close console (file) - we close the end end return M  

we Will consider main.lua

  - main.lua LOG = require "libLog" - we connect library - we write down to local write_data ravine = "Very important entry in the log" - a line for for i file recording = 1,10 do LOG.write (write_data. '-'. . i) end - we unload ravine contents in the LOG.read console ()  

Date and time


In many developed languages like C%23 or Delphi work with date and time is carried out due to use of tens ready functions which on the one hand all the same cannot provide all and something is necessary "dopilivat", on the other hand the brittle brain of the developer is compelled to store in itself all this zoo of opportunities. In Lua everything is extremely simple:

  • of os.time () — returns UNIX time , proceeding from parameters it can be various
  • os.date
  • () — accepts UNIX time and a set of parameters, returns either the table with values or the formalized line if not to specify UNIX time the table flowing time will be returned.
T.O's
. only two functions, but are used they very flexibly and it allows to solve the most part of necessary tasks of work with date and time. There is one more additional functions indirectly connected with time — os.clock, this function allows to define time of performance of a code. Let's consider all these functions in details.

of os.time ()

In the simplest option function is caused by
without parameters and returns the current system timestamp (UNIX time / POSIX — time ) — this number of seconds which passed from the moment of the beginning of an UNIX era ( 01.01.1970 at 00:00:00 UTC ).

  of print (os.time)->> 1513065913 (at you will be more)  

In an expanded format the os function.time is capable to return timestamp of any point of time after the beginning of an UNIX era, for this purpose it is necessary to transfer functions as parameter the table in a special format: date table. That "magic" in this table is not present I give its description below: if summertime I.e. if to fill in this table and to transfer her to os.time function will return

of year 1970-3000
month 01-12
day 01-31
hour 00-23
min 00-59
sec 00-59
isdst true to

for the established timepoint of timestamp. Parameters year, month, day are obligatory. As there are time frames within which it is possible to enter parameters they stretch from the beginning of an UNIX era and to () if to enter above and below these limits function will return to 31.12.3000 23:59:59UTC
Pay attention, time parameters: hour, minute, second are by default used 0:00:00 PM values. In such application it is convenient to use the os.time function for comparison of dates, much more convenient than to do difficult round in the date table parameters. It is possible as to use result of this function for calculation "how many remained to. " or "how many passed page. . " , the only inconvenience will be that what to put from seconds in days clock, minutes and seconds nevertheless it is necessary in manual, but it is not difficult. I will give an example which to calculate remained time about New Year in days of hour minutes and seconds:

  - we receive the next year local year = os.date ('*t'). year %2B 1 - this "magic" becomes clear very soon - we receive chsilo seconds to "Nezavisimaya gazeta" local before_NY = os.time { year = year, month = 1, day = 1, hour = 0 } - os.time () local s_day, s_hour, s_min = 24*60*60, 60*60, 60 - number of seconds in days, hour, minute of local day = math.floor (before_NY/s_day) - number of days of local hour = math.floor ((before_NY - day * s_day) / s_hour) - local min number of hours = math.floor ((before_NY - day * s_day - hour * s_hour) / s_min) - number of minutes of local sec = before_NY - day * s_day - hour * s_hour - min * s_min - number of seconds of print (string.format ('Until the New Year there are %d days %d hours %d minutes %d seconds', day, hour, min, sec))  

of os.date


Despite the name, the os.date function is inverse function from os.time, i.e. from the low-level timestamp format she receives more high-level date table format, in returned result of the os.date function there are fields which the os.time functions are not required these are fields: yday — day of year ( 1. 365 or 366 for leap-years ) and wday — day of week ( 1 — Sunday, 2 — Monday … 7 — Saturday ). Function accepts 2 parametra:

  • Formatiruyushchaya line — this line defines an output format data, for this purpose what to receive the table data table as result it is necessary to use one of two keys of "*t" — date time come back taking into account your temporary zone (i.e. that hours on the computer ), "show the same time! *t" — date time come back without a temporary zone, on UTC time. If not to use a key, it is necessary to enter a line defining an output format, thus result it will be returned in the form of a line, places of an insert of information and its type are defined by tags which begin the % symbol, the complete list of possible tags is provided after the list.
  • UNIX time — this parameter is not obligatory and the current time of system is by default used.

  • of %a the Reduced English name of day of week
  • %A
  • the Full English name of day of week
  • %b
  • the Reduced English name of month
  • %B
  • the Full English name of day of week
  • %c
  • Date and format time: 09/16/98 23:48:10
  • %d
  • Day of month [01-31]
  • %H
  • Hour in a full format [00-23]<"169>" %I
  • Hour in the am/pm [01-12]
  • of %M of Minute [00-59]
  • %m
  • Months [01-12]
  • of %p "am" or "pm"
  • of %S of Second [00-61]
  • %w
  • Day of week [0-6 = Sunday-Saturday]
  • %x
  • Date a format: 09/16/98
  • %X
  • Time format: 23:48:10
  • %Y
  • Year full format [1970-3000]
  • %y
  • Year "two figures" format: [00-99]
  • %% the % Symbol in a line of formatting

Is passed with
  • to examples of use of os.date:

      - [[SUPPORT FUNCTION]] - function removes table date table print_dt contents = function(t) local s = '' for k, - pass according to the table local vv = type(v) == 'boolean' - if the boolean and parameter (v and 'true' or 'false') - we form v in pairs (t) of do the lines or v - if not boolean simply we equate v s = s. string.format (' %s = s %,', k, vv) - we link the line end print (s) of end - [[EXAMPLES of USE of os.date About REZULYAT'S RECEIVING - TABLES]] print_dt (os.date ('*t')) - the current time taking into account a belt->> hour=21, min=4, wday=3, day=12, month=12, year=2017, sec=14, yday=346, isdst=false, print_dt (os.date ('! *t')) - the current time without a belt->> hour=18, min=4, wday=3, day=12, month=12, year=2017, sec=14, yday=346, isdst=false, print_dt (os.date ('! *t', 1000000000)) - date time in milliard second of an UNIX era->> hour=1, min=46, wday=1, day=9, month=9, year=2001, sec=40, yday=252, isdst=false, - [[EXAMPLES of USE of os.date About REZULYAT'S RECEIVING - LINES]] print (os.date ('Now: %c')) - Now: 12/12/17 9:04:14 PM print (os.date ('Date: %x')) - Now: 12/12/17 print (os.date ('Time: %X')) - Now: 9:04:14 PM print (os.date ('2^9 sec UNIX-time: %c', 2000000000)) - Now: 2^9 sec UNIX-time: 05/18/33 06:33:20  

    of os.clock


    it is frequent in the course of an application creation there are problems with a productivity and it is not always simple to understand what specifically a code fragment strongly loads all appendix, or for example leads to long starts of the program. As it is possible to choose by means of function what option of realization of the same function to choose. The os.clock function — returns time in seconds ( accuracy to 4 signs after a comma ) which was spent by the processor on working over the appendix from the moment of appendix start. I.e. if to curtail the appendix into memory and not to use it — counting of time it will be suspended before return to the appendix. Example of a code comparing efficiency of two options of performance of one task, an example naturally comic ( all and without tests will guess that works quicker ).

      - is comparable as more effective to consider the sum of numbers of a row 1. N func1 = function(N) - the suitable return function (N* (N%2B1))/2 end func2 = function(N) - realization "in a forehead" local sum = 0 for i=1, N do sum = sum %2B i end return sum end local N = 1000000000 - we calculate the sum of numbers from 1 to N local x = os.clock () func1(N) print ('funt1: '. (os.clock () - x). ' sec')->> funt1: 0 sec x = os.clock () func2(N) print ('funt2: '. (os.clock () - x). ' sec')-> funt2: 6.293  

    in the course of studying of this article I told more than once sec
    — a fragment of a program code (subprogramme) to which it is possible to address from other place of the program. In most cases the identifier contacts function, but many languages allow also anonymous functions.

    Anonymous functions


    of Lua allows existence anonymous ( depersonalized, anonymous ) functions — it is everywhere applied in case one function demands as one of arguments other function and if this fragment to you create anonymous function more where it is not useful you with easy soul. I will give an example:

      of func1 = function(func) - function demands function as the func parameter () - start of the end function transferred in parameter - we cause the func1 func1 function (function () - we realize the anonymous print function ('Hi from an anonymous function! ') end)  
    the Order of the announcement of functions
    you most likely already noticed

    , but nevertheless I will sum up, function in Lua can declare in two ways: Assignment of its value of the
    variable
    of
      of name1 = function () end  

    the Direct announcement
    of
     of function name2 () end  

    you can use

    any way, but the first as the small difference is is better — at the time of initialization of the module (file) in it all local context i.e. if out of functions there are any assignments of variables is at a time carried out, they will be once appropriated (function declared as the variable will be initialized), if to declare function will be initialized by the second way at the first use.

    the Order of a call of function


    Function is caused by a way of the indication of her name and in brackets of transfer of parameters if not to specify a bracket function it will be simple to store the type of data and the call address, you you can simply print function in print and she thus will not be called:

      of function func1 () print ('Hi') of end print (func1)->> function: 005DBA00 (at you it will be possible other address) print (func1)-> notice here that did not return - to print not that  

    of the Second print that did not print as function has no returned parameters. There is one more option of the organization of a call of function. In functions the set of input parameters can be required and they can either be transferred through a comma or to organize function so on an entrance she would expect only one parameter — table, and in it in a format a key = value all parameters are placed:

      - function with the list of the func1 parameters = function (a, b, c) print (a, b, c) end - function with the table parmetrov func2 = function(p) print (p.a, p.b, p.c) end - func1 func1(1,2,3) call->> 1 2 3 - func2 func2 call {->> 4 5 6 a = 4, b = 5, with = 6 }  
    At first sight can seem to
    that the 2nd way "any long — to write much", but in practice it is one many more convenient, I will adduce arguments in protection "long way", probably it will be possible to convince you that it is good:

    • If you have only the third parameter that function of the first type will demand from you to hammer nil-ami other parameters what to reach to 3 func1 parameters (nil, nil, 3), for the second way everything is simpler func2 { with = 6 }
    • Using the first way to you it is necessary to have before eyes realization of function what not to hammer in what sequence it is necessary to enter values, in the second case it has no what value and so the same will work with func2 { with = 6, b = 5, a = 4 }
    • If parameters much that can transfer in the second way to
    • them previously having placed to the separate table and further to make the accurate call which is not breaking symmetry of function, in the first case you will be always obliged to do a long call
    • to
    • For the second case you can have a template of parameters in the form of the table and before transfer of parameters simply fill those values which do not suit you in a template by default, for the first option — only as always.

    Wants to believe that your choice in case parameter as more than one will always incline to the second option, but to solve only to you.

    Return of results


    Here everything is simple that function would return something it is necessary at that moment when the result is received the operator of return after which will use to go a variable (or some variables). As well as in case of transfer of parameters of function, and in case of return of results of performance I to you would recommend to use resulting tables in which all results are placed:

      - function with the list of the func1 parameters = function (a, b, c) return a%2Bb, b%2Bc, c%2Ba - result the end list - function with the table parmetrov func2 = function(p) return { p1 = p.a%2Bp.b, - result the table p2 = p.b%2Bp.c, p3 = p.c%2Bp.a } end - a call of func1 val1, val2, val3 = func1 (1,2,3) print (val1, val2, val3)->> 3 5 4 - func2 val call = func2 { a = 4, b = 5, with = 6 } print (val.p1, val.p2, val.p3)->> 9 11 10  

    Regular expressions and captures


    you faced concepts of regular expressions and captures when studying this article already several times, in particular when studying the following functions: string.match, string.gmacth, string.sub, string.gsub, string.find . How it works? I will bring most a little terms.
    Regular expression — is a line consisting of sequence of symbols defining a template of analysis of a text line on components.

    Regular expression can consist of operating designs, continuous sequences of symbols and captures.

    the Operating design — is a template of regular expression which can replace with itself one or several symbols, i.e. for example %d — this any number. The complete list of operating designs is given below:

    • . — any symbol
    • %a
    • — a Latin letter
    • %s — a control symbol
    • %d
    • — decimal figure
    • %u
    • — a Latin letter of the top register
    • %l
    • — a Latin letter of the bottom register
    • %p
    • — a sign of a punctuation
    • %s
    • — a symbol of a gap
    • %w
    • — a Latin letter or the Arab figure
    • %z
    • — a zero symbol
    • %A
    • — not a Latin letter
    • %C
    • — not a control symbol
    • %D
    • — not decimal figure
    • %U
    • — not a Latin letter of the top register
    • %L
    • — not a Latin letter of the bottom register
    • %S
    • — not a symbol of a gap
    • %W
    • — not a Latin letter and not the Arab figure
    • %Z
    • — not the zero symbol

    Is available opportunity some operating designs to unite in one, for this purpose they need to be placed in square brackets "[]". Pay attention that for the majority of operating designs there are 2 mutually exclusive options for example %w and %W actually can invert any design a cover symbol "^", i.e. ^ w % analog of %W and vice versa ^ W % analog of %w. As the most part of standard managing directors of designs can be organized manually for example for %d analog [0-9], for %w — [0-9a-zA-Z], for brevity there where it is possible to apply the reserved standard designs better.

    Continuous sequence — is strict sequence of symbols which has to be in strictly certain place of regular expression. Let's give an example there is a line "param1: 1234, param2: 54321", we use the following regular expression for its analysis "%d%2B" ( any quantity of symbols going in a row means, but not less than 1 ). This regular expression will find the line "1234" and function will return result if we need receive value of the second parameter we we can or start search the second time of times (using the sootvetsuyushchy parameter of functions), or it is simple to specify continuous sequence symbols, namely "by params2: " and regular expression will have an appearance:" params2: %d%2B" and if to go further and it to simplify having cast away excess that remains "2: %d%2B". It is worth noticing that after reduction of length of continuous sequence universality of regular expression will increase and at bigger number of parameters there can be a miss.

    Capture — this room in a variable of certain parts of a line by analysis by its regular expression. What to organize capture it is enough to place some part of regular expression in parentheses" ()". In one regular expression there can be a set of captures. Capture example: there is an initial line" ip:123.22.345.23
    ", it is necessary to take all 4 numerical parts of ip of the address, we will apply the following regular expression as argument of the string.match function "ip:(%d%2B) %. (%d%2B) %. (%d%2B) %. (%d%2B)" the code will look approximately so:

      of local st = local reg "ip:123.22.345.23" = "ip:(%d%2B) %. (%d%2B) %. (%d%2B) %. (%d%2B)" local d1, d2, d3, d4 = string.match (st, reg) print (d1, d2, d3, d4)->> '123' '22' '345' '23'  

    Pay attention that the point symbol between captures needs to be shielded as this symbol is operating design and any symbol " if it not to make number means" it will be possible to divide any symbol and capture will work all the same. There are also other symbols which in a body of regular expression it is necessary to shield here their list:

    (). % %2B — *? [] ^ $

    it is IMPORTANT : In regular expressions there is a strict need of performance of all conditions, i.e. if one condition of analysis of a line all capture is not satisfied at least is not satisfied, and about all variables receive nil value. to

    How to make captures by more universal, for example to leave opportunity that the third of ip for any reason will be absent? Actually everything is simple — now we use in "%2B" together with operating design of %d, and it assumes existence at least one number if to clean %2B, the condition will be such — has to be strictly one symbol if instead of "%2B" the symbol "*" is to set that condition — capture of any quantity of numbers including any. We check:

      of local st = "ip:123.22. 23" local reg = "ip:(%d%2B) %. (%d%2B) %. (%d *) %. (d%2B %)" local d1, d2, d3, d4 = string.match (st, reg) print (d1, d2, d3, d4)->> '123' '22' '' '23'  
    Everything perfectly worked
    . We pass to the following complication that if line contains number in a hexadecimal format, i.e. on by figures may contain abcdefABCDEF symbols. For this task we will unite some operating designs in one with the help" []", operating signs %2B * need to be put outside square brackets, or they the same will be considered part of a total design. What not to list all symbols (symbols going in a row are if ) it is possible they can be grouped and listed through a hyphen as follows "a-fA-F"

      local st = "code = 12f3a2e2ffd423A;" local reg = "code = ([a-fA-F%d] %2B)" local code = string.match (st, reg) print(code)->> '12f3a2e2ffd423A'  

    Now we will consider option simplification of this regulyarka. Let's try to go from the return i.e. to look for not certain symbols, and to take all symbols except a finishing symbol, in this case ";" . As it was written above what to initiate inverting "all but" it is necessary to put a cover symbol "^" before operating symbol. As for specifically this case it is possible to simplify strongly continuous sequence before capture of all to "=" if not to make it the first symbol of the line "code" will be taken as he too answers regular sequence and if to put only a gap "" the excess fragment "=" will be taken.

    we Watch a code:

      of local st = "code = 12f3a2e2ffd423A;" local reg = "= ([^; ] % 2B)" local code = string.match (st, reg) print(code)->> '12f3a2e2ffd423A'  

    In capture I can be present as sequence a symbol on slightly separate or grouped operating designs, i.e. captures of such look too are correct:

     " (buka[%d] %2B%s * %. [w %] * [^ %% 2B] %2B)".  

    Regular expressions in Lua are serious part of system and not seldom allow to simplify many things considerably. I will give some councils for an order of application of regular expressions:

    • Try to do a regulyarka by the simplest and obvious way
    • Always make comments that does a fragment with regular expression
    • to
    • If in regular expression there was a mistake and you know that it does, it has to is better to write it anew than to try to correct

    On postdock I will give an example of function of a validity of email doing "weak" check.

      - check of a validity of email check_email = function(email) local a, b, c = string.match (email,' ([^ @] %2B) @ ([^ %. ] [^ %. ] % 2B) %. (. %2B)') return a ~ = nil and b ~ = nil and c ~ = nil end  

    Is expression works by the following rule:

    • 1 capture — has to go at least one symbol not "@" — a user name
    • a symbol "@"
    • 2 capture — there have to be at least two symbols not "." — the domain 2 of level
    • a symbol "."
    • 3 capture — at least one any symbol — the domain 1 of level

    At first sight is the mass of ways to enter bad email, but in practice it is admissible severity of check of this parameter.

    Management of accident


    Very often in real appendices is required to bring some accident, for example to choose one of in advance defined values or to set the casual direction, color, etc. For the solution of these tasks in the majority of languages there is a generator of psevdosluchany numbers.

    Mathematically to create casual sequence on the present, meanwhile it is considered impossible, there are hardware decisions solving this problem, but it is separate history . In Lua the generator, for receiving pseudorandom numbers is used the math.random function (). The generator operates on a certain algorithm of times in any time sequence begins will repeat, length of sequence can be rather big, but there is a minus each time at an application launch sequence begins anew i.e. if for example, at an entrance to the appendix the program we receive a random number from 1 to 100, each time we will see the same result if we put this action on an entrance to the appendix:

      of print (math.random(1,100)) - the first random number 1. N always 1)<"278>"  

    will Always turn out 1, it is unconditional very inconveniently, in real tasks. In attempt to solve this problem it is possible to use the second function of math.random intended for management, this math.randomseed function — by means of it we can change the first step of casual sequence and generation will begin not with unit, and with another ( always identical ) numbers.

      of local seed = 1234567890 math.randomseed(seed) print (math.random(1,100)) - the first random number 1. N always 4)<"281>"  

    Now each time at an entrance to the appendix we see number 4. Something again not so! Obviously on a generator entrance through math.randomseed it is necessary to give not always the same seed. How to receive it? It is possible to try to use as seed already known os.time function (), in this case if to enter the appendix less often than once a second we will receive different number:

      of math.randomseed (os.time) of print (math.random(100)) - value changes if from last start there passed 1 second  

    If knows that change of seed would happen approximately in 10000 quicker, it is possible to use in such a way:

      of socket = require ("socket") of local seed = (socket.gettime () *10000) %10^9 math.randomseed(seed) print (math.random(100)) - value changes if from last start passed more than 100 microseconds  

    the Inquisitive reader will sort it an example.

    On postdock we will consider all options of application of math.random

      local n, m = 100,200 math.random(n) - number from 1 to n math.random (n, m) - number from n to m math.random (-m, m) - the beginning of the period can be negative math.random (-m, - n) - the beginning and the end of the period can be negative, but the end has to be closer to zero math.random () - the random real number from 0 to 1 (to 16 signs after a comma)  
    by
    About the FUTURE is generated: In the course of Corona SDK studying we will experiment entering of entropy into the mechanism of generation of numbers, for example receiving signals of fluctuations from the sensor of the accelerometer or other sensors, it is a way is on the present casual, but is not mathematical and as time of quantization (poll) at all sensors makes kilohertzes, and cycle for performance (with a small number of teams) can borrow much less time, problems with this way will be not less essential, we should or slow down a cycle until sensor quantization, or to use additional sources of entropy.

    Wants to note that in creation questions very much realistic accident should not torment strongly itself, even the notable slogger mathematician John fon Neyman used to say:
    "Everyone who has a soft corner in the heart for arithmetic methods of receiving random numbers, is guilty out of any doubts. "
    Mathematical functions
    B previous the section were described by

    of the random and randomseed function from library of the mathematical math functions. In this library there are also other functions which will be useful sooner or later to you.

    • of abs (x) Returns the module of number x.
    • of ceil (x) are Returned by the smallest integer, bigger or equal set x (carries out rounding "up").
    • of floor (x) are Returned by the greatest integer, smaller or equal set x (carries out rounding "down").
    • max
    • (....) Returns maximum of arguments (accepts a set of arguments).
    • min
    • (....) Returns minimum of arguments (accepts a set of arguments).
    • fmod
    • (a, b) Returns a remainder of division on b.
    • to
    • of modf (f) Returns the whole and fractional parts of initial number of f.
    • to
    • of frexp (x) Returns the normalized mantissa and an argument indicator. x = m2e
    • ldexp
    • (m, e) Builds number on a mantissa and an indicator. m2e (e has to be whole)
    • pow
    • (x, y) Builds number x in y degree. Instead of a call of function use of expression of a type of x^y is possible.
    • of sqrt (x) are Calculated by a square root of number x. Instead of a call of function use of expression of a type of x^0.5 is possible.
    • of exp (x) are Returned by ex.
    • of log (x) are Calculated by a natural logarithm x.
    • of log10 (x) are Calculated by a logarithm x on the basis 10.<"308>"
    • of cos (x) are Calculated by a cosine of the angle x, set in radians.
    • of sin (x) are Calculated by a sine of the angle x, set in radians.
    • of tan (x) are Calculated by a tangent of angle x, set in radians.
    • of cosh (x) are Calculated by a hyperbolic cosine.
    • of sinh (x) are Calculated by a hyperbolic sine.
    • of tanh (x) are Calculated by a hyperbolic tangent.
    • of acos (x) are Calculated by an arccosine (in radians).
    • of asin (x) are Calculated by an arcsine (in radians).
    • of atan (x) are Calculated by an arctangent (in radians).
    • atan2
    • (x, y) Returns an arctangent x/y (in radians), but uses signs of both parameters for "quarter" calculation on the plane. Also correctly processes a case when y is equal to zero.
    • to
    • of deg (x) Transfers corner size from a radian to degrees.
    • to
    • of rad (x) Transfers corner size from degrees to radians.

    On by functions in math library is available also 2 constants — math.pi
    and math.huge . We already got acquainted with math.pi in the first part of article and it simply a constant storing all known variable (Pi), the accuracy of a constant is sufficient for the majority of cases — 3.1415926535898. The constant math.huge more mysterious essence its feature — it always more or is equal any numerical value.

    Careful attitude to the stranger...


    B of this short and final the section we will talk at all that to the car hired it is worth treating as the, it will be a question of standard functions of language. At this moment I decided not to add 2 more sections in article and removed them, there is a strong wish to finish and sleep: (. In many languages it is rather difficult to spoil standard functions, in Lua — is not present than that it is simpler. Let's appropriate to any function any value. I will give an example:

      of print = 1 - pereinitsializiruy print print value ('Hello World') - a mistake "attempt to call global 'print' (a number value)"  

    As you can see to spoil that not a lot of things that is in this language very simply. Reserved words like end, begin, then thus not to spoil, and here other functions are absolutely defenseless before manifestation of small carelessness. Such mistakes will very not be simple to be found, especially if in the project tens of thousands of lines and over it the lot of people works. I can give only one advice always use editors of a code with illumination of the Lua code and it is desirable the Corona SDK functions and if that you decided to make that a variable or function name somewhere it is already used — think up a new name .

    If an example with print initialization seems to you a little" farfetched ", I will give much more real example which bears still big consequences and comes to light even more difficult.

    the Developer decided to enter in the program a logical flag truth assignment (true ) to which, the press in the console of debugging information will resolve. Without hesitation he solved that names everyone translitas (like OTLADKA ) at all do not suit for its project and called the debug variable. Appropriated to the true variable, checked that everything works and continued to develop further, in hour, day or more someone from his colleagues noticed that Corona SDK absolutely broke and at all does not give out an error message even if you write totally ludicrous in a code. It appeared that the debug function — is the standard Lua function which besides that can be useful to you in debugging so also is used by the crown and its elimination completely breaks system of debugging of errors of the project. I think, it is rather good example confirming idea that need careful attitude to the stranger … to

    the Conclusion

    to
    If you studied all three parts of article that you received the most part of that that you will need to know what surely to create the projects on Corona SDK. I considered some questions too in detail, to another probably paid not enough attention, somewhere probably I was not right or is not exact, but there is a wish to trust that there will be people to whom this information will help. Many things from additional libraries of language remained beyond the scope of this article it is connected with that that to some Lua functions there is more acceptable replacement from the Corona SDK functions. In the following articles we will study any more Lua, namely Corona SDK i.e. which that functionality in pure form in language is not present. You are waited by all means by a set of articles in which we will write games and to do other useful things. the gratitude for help given in article writing Wants to express

    , to those people who make comments and point to inaccuracies, as to developers of a cursor with whom I had honor to communicate and consult through their groups in social networks ( VK and facebook ) and the Slack-channel (an entrance free) .

    All thanks and good luck! Yours faithfully, Goncharov Denise aka execom email
    : PS
    : And that who all this read thanks.