Lua4.0 Reference Manual (iv) 4.6-4.8

Source: Internet
Author: User

(Part 1)
-------------------
4.6 visibility and upvalue
-------------------
A function body can reference its own local variables (including its parameters) and global variables, as long as they are not hidden by local variables with the same name in the function (shadowed ). A local variable that cannot contain the function, because such a variable may no longer exist when the function is called. However, a function can use the local variables in its functions through upvalue. Upvalue Syntax:
Upvalue: = '%' name
A upvalue is somewhat like a variable expression, but its value is frozen (frozen) when its function is instantiated. The name used in upvalue can be the name of any variable, as long as the variable is visible when the function is defined, that is, the global variables and local variables in its function are directly included. Note that when upvalue is a table, only the reference of the table (that is, the value of upvalue) is frozen. The table content can be modified at will. Using the table value as upvalue allows the function to be writable but private.
The following are some examples:

    a,b,c = 1,2,3 -- global variables    local d    function f (x)      local b = {} -- x and b are local to f; b shadows the global b      local g = function (a)        local y -- a and y are local to g        p = a -- OK, access local `a‘        p = c -- OK, access global `c‘        p = b -- ERROR: cannot access a variable in outer scope        p = %b -- OK, access frozen value of `b‘ (local to `f‘)        %b = 3 -- ERROR: cannot change an upvalue        %b.x = 3 -- OK, change the table contents        p = %c -- OK, access frozen value of global `c‘        p = %y -- ERROR: `y‘ is not visible where `g‘ is defined        p = %d -- ERROR: `d‘ is not visible where `g‘ is defined      end -- g    end -- f

-------------------
4.7 handle errors
-------------------
Because Lua is an extension language, all Lua Actions start from the C code in the Host Program Calling a function in the Lua library. Every time an error occurs during Lua compilation or execution, function _ errormessage will be called (if it is not nil), and then functions in the corresponding Library (lua_dofile, lua_dostring, lua_dobuffer and lua_call) terminated and an error is returned.

Memory Allocation Error is an exception of the above rule. When memory allocation fails, Lua may not be able to execute the _ errormessage function. Therefore, for this error, Lua does not call the _ errormessage function. Instead, the corresponding function in the library immediately returns a special error code (errmem. This and other error codes are defined in Lua. H. See section 5.8.

The unique parameter _ errormessage is a string with an incorrect description. The default definition of this function is _ alert, which prints information to stderr (see section 6.1 ). The standard I/O Library redefined _ errormessage and used the debugging mechanism (see section 7) to print some additional information, such as calling stack backtracking.

The Lua code may generate an error by explicitly calling the function error (see section 6.1. The Lua code can capture an error using the function call (see section 6.1.

-------------------
4.8 Tag Method
-------------------
Lua provides a powerful mechanism to expand its semantics, called Tag Method ). A tag method is a function defined by a programmer to call at a specific key point in Lua program execution. It allows the programmer to change the standard Lua behavior at these key points. Every such point is called an event.

The Tag Method of a specific event is called Based on the tag of the value involved in the event (see section 3 ). The settagmethod function changes the TAG method associated with a given pair (TAG, event. Its first parameter is the tag, the second parameter is the event name (a string, see below), and the third parameter is the new method (a function ), or nil is used to restore the default behavior of a pair (TAG event pair. The settagmethod function returns the previous Tag Method for the tag event. The corresponding function gettagmethod receives a tag and an event name and returns the associated current method.

The label method is called in the following events, which are differentiated by the given name. The semantics of the label method can be better interpreted by the Lua function to describe the interpreter's behavior in each event. This function not only shows when the label method will be called, but also shows its parameters, return values, and default behavior. The code shown here is only used to illustrate the purpose; the real behavior in the interpreter is hard-coded, and it is more efficient than this simulation. All the functions used in these interpretations (rawget, tonumber, call, etc.) are described in section 6.1.

''Add '':
It is called when the + operation is applied to non-numeric operands.
The following function getbinmethod defines how Lua selects a label method for a binary operation. First, Lua tries the first operand. If its label does not define the label method for the operation, Lua tries the second operand. If it still fails, then a TAG method is obtained from tag 0.

    function getbinmethod (op1, op2, event)      return gettagmethod(tag(op1), event) or             gettagmethod(tag(op2), event) or             gettagmethod(0, event)    end

Using this function, the TAG method of the ''add'' event is:

    function add_event (op1, op2)      local o1, o2 = tonumber(op1), tonumber(op2)      if o1 and o2 then -- both operands are numeric        return o1+o2 -- ‘+‘ here is the primitive ‘add‘      else -- at least one of the operands is not numeric        local tm = getbinmethod(op1, op2, "add")        if tm then          -- call the method with both operands and an extra          -- argument with the event name          return tm(op1, op2, "add")        else -- no tag method available: default behavior          error("unexpected type at arithmetic operation")        end      end    end

''Sub '':
This operation is called when it is applied to non-numeric operands. Its behavior is similar to the ''add'' event.

''Mul '':
This operation is called when * is applied to non-numeric operands. Its behavior is similar to the ''add'' event.

''Div '':
It is called when the/operation is applied to non-numeric operands. Its behavior is similar to the ''add'' event.

''Pow '':
When a ^ (Power) operation is called, even for numeric operands.

    function pow_event (op1, op2)      local tm = getbinmethod(op1, op2, "pow")      if tm then        -- call the method with both operands and an extra        -- argument with the event name        return tm(op1, op2, "pow")      else -- no tag method available: default behavior        error("unexpected type at arithmetic operation")      end    end

''Unm '':
It is called when the unary operation is applied to non-numeric operands.

    function unm_event (op)      local o = tonumber(op)      if o then -- operand is numeric        return -o -- ‘-‘ here is the primitive ‘unm‘      else -- the operand is not numeric.        -- Try to get a tag method from the operand;        -- if it does not have one, try a "global" one (tag 0)        local tm = gettagmethod(tag(op), "unm") or                   gettagmethod(0, "unm")        if tm then          -- call the method with the operand, nil, and an extra          -- argument with the event name          return tm(op, nil, "unm")        else -- no tag method available: default behavior          error("unexpected type at arithmetic operation")        end      end    end

''Lt '':
When a comparison operation is applied to non-numeric or non-string-type operands, it is called. It is equivalent to the <operator.

    function lt_event (op1, op2)      if type(op1) == "number" and type(op2) == "number" then        return op1 < op2 -- numeric comparison      elseif type(op1) == "string" and type(op2) == "string" then        return op1 < op2 -- lexicographic comparison      else        local tm = getbinmethod(op1, op2, "lt")        if tm then          return tm(op1, op2, "lt")        else          error("unexpected type at comparison");        end      end    end

Other comparison operators use this label method based on common adequacy:
A> B <=> B <
A <= B <=> not (B <)
A> = B <=> not (a <B)

''Concat '':
It is called when the join operation is applied to non-string-type operands.

    function concat_event (op1, op2)      if (type(op1) == "string" or type(op1) == "number") and         (type(op2) == "string" or type(op2) == "number") then        return op1..op2 -- primitive string concatenation      else        local tm = getbinmethod(op1, op2, "concat")        if tm then          return tm(op1, op2, "concat")        else          error("unexpected type for concatenation")        end      end    end

''Index '':
When Lua tries to return an index that is not in the table, it is called. For the semantics, see the ''gettable'' event.

''Getglobal '':
When Lua needs a value of a global variable, it is called. This method can be set only for nil, and only for the tag created by newtag. Note that the label is the current value of the global variable.

    function getglobal (varname)      -- access the table of globals      local value = rawget(globals(), varname)      local tm = gettagmethod(tag(value), "getglobal")      if not tm then        return value      else        return tm(varname, value)      end    end

The getglobal function is defined in the basic library (see section 6.1 ).

''Setglobal '':
When Lua assigns a value to a global variable, it is called. This method cannot be set for values, strings, tables, and userdata with default tags.

    function setglobal (varname, newvalue)      local oldvalue = rawget(globals(), varname)      local tm = gettagmethod(tag(oldvalue), "setglobal")      if not tm then        rawset(globals(), varname, newvalue)      else        tm(varname, oldvalue, newvalue)      end    end

The setglobal function is defined in the basic library (see section 6.1 ).

''Gettable '':
When Lua calls an index variable, it is called. This method cannot be set for tables with default labels.

    function gettable_event (table, index)      local tm = gettagmethod(tag(table), "gettable")      if tm then        return tm(table, index)      elseif type(table) ~= "table" then        error("indexed expression not a table");      else        local v = rawget(table, index)        tm = gettagmethod(tag(table), "index")        if v == nil and tm then          return tm(table, index)        else          return v        end      end    end

''Settable '':
It is called when Lua sets an index variable. This method cannot be set for tables with default labels.

    function settable_event (table, index, value)      local tm = gettagmethod(tag(table), "settable")      if tm then        tm(table, index, value)      elseif type(table) ~= "table" then        error("indexed expression not a table")      else        rawset(table, index, value)      end    end

''Function '':
When Lua tries to call a value that is not a function, it is called.

    function function_event (func, ...)      if type(func) == "function" then        return call(func, arg)      else        local tm = gettagmethod(tag(func), "function")        if tm then          for i=arg.n,1,-1 do            arg[i+1] = arg[i]          end          arg.n = arg.n+1          arg[1] = func          return call(tm, arg)        else          error("call expression not a function")        end      end    end

''Gc '':
When Lua recycles a userdata, it is called. This label method can only be set in C and cannot be set to userdata with default labels. For each userdata recycled by garbage collection, Lua is equivalent to the following function:

    function gc_event (obj)      local tm = gettagmethod(tag(obj), "gc")      if tm then        tm(obj)      end    end

In a garbage collection cycle, the TAG method of userdata is called in the reverse order of tag creation. That is to say, the first Tag Method to be called is associated with the last tag created in the program. In addition, at the end of the cycle, Lua is equivalent to a gc_event (NiL) Call.
(To be continued)

Lua4.0 Reference Manual (iv) 4.6-4.8

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.