lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


2014-08-24 5:05 GMT+02:00 Paul Merrell <marbux@gmail.com>:
> Hi, all,
>
> After a couple of years now, I think I'm approaching an understanding
> of Lua's variable scoping.

It is clearer but more verbose to avoid speaking of global variables.
"Global variable" is shorthand for "value associated with globally
visible name". Globally visible names are, in Lua 5.2, keys in the
table _ENV.

> But where I'm still at sea is in evading the use of globals in an
> if block or loop inside a function.

Every value that you do not need to have a side effect outside
the function should be declared as local inside the function.

> A function begins at line 43 and a series of if blocks at line 48.
> The variables within each if block are globals. How might I refactor
> my function so that the same variables are locals, if possible.

Local variables are genuine variables, in the sense that when you
declare them, some memory gets reserved for them _even if they
have the value nil_, and in the bytecode they are referred to by
their stack slot number, never by name (unlike globals, which get
looked up every time you access them).

So all you need is one extra line to declare them local, but _outside_
all the `if` blocks.
---

function Test_Read_Only_Properties(nDocID, strNoteID)

local nReadOnlyNote = Nc_Note_Flag_ReadOnly_Get(nDocID, strNoteID)
local nReadOnlyDoc = Nc_Doc_ReadOnly_Get(nDocID)
local strMessage, bTerminate   -- reserves stack slots for these

if nReadOnlyNote == 0 and nReadOnlyDoc == 0 then
strMessage = "" -- both read/write
bTerminate = false
end

if nReadOnlyNote == 0 and nReadOnlyDoc == 1 then
strMessage = "ERROR:  The document is read-only. Cannot make requested
change(s). Terminating script. To proceed, open the Document
Properties dialog and change its read-only setting. Then try again."
bTerminate = true
end

if nReadOnlyNote == 1 and nReadOnlyDoc == 0 then
strMessage = "ERROR:  The note is read-only. Cannot make requested
change(s). Terminating script. To proceed, open the Note Properties
dialog and change its read-only setting. Then try again."
      bTerminate = true
end

if nReadOnlyNote == 1 and nReadOnlyDoc == 1 then
strMessage = "ERROR:  Both the document and note are read-only. Cannot
make requested change(s). Terminating script. To proceed, open the
Document Properties dialog and change its read-only setting. Open the
Note Properties dialog and change its read-only setting. Then execute
the script again."
bTerminate = true
end

 return strMessage, bTerminate

end --  function
---

> I've been working around this kind of problem by declaring the globals
> as nils in the global environment. See function test at line 79.

-- declares globals needed in function
strMessage = nil
bTerminate = nil

That comment is wrong. Those two statements in fact _remove_
the corresponding global variables if they existed, since in Lua 5.2
they are equivalent to

_ENV.strMessage = nil
_ENV.bTerminate = nil

which removes the keys concerned from the table _ENV.