User Tools

Site Tools


lgscript:lua_blocks

Blocks

Scripts are arranged into blocks of statements. A statement is an assignment, a local declaration, a function call, or a nested block. A script file is its own block and is also known as a chunk.

Blocks can be nested as long as each inner block ends before the outer block ends.

A simple block can be created with the keywords do and end. You can use this to create a specific scope for a local variable.

Other blocks change the flow of the script, along with creating a new scope.

If-Then-Else

An if-then-else conditional block tests a value then runs the statements in the block and skips over statements in another block.

if i == 0 then
    print("i is zero")
end

if i > 0 then
    print("i is not zero")
else
    print("i is zero")
end

More than one test can be chained together with elseif.

if i == 0 then
    print("i is zero")
elseif i == 1 then
    print("i is one")
elseif i == 2 or i == 3 then
    print("i is prime")
else
    print("i is not prime")
end

Parenthesis are not needed around the test, but they won’t hurt either. The then and end keywords are required. An entire if-then-else statement can be written on a single line.

While

A while loop tests a value then runs the statements in a block if it is true. After the block ends, the value is tested again and the block run again if it is still true.

while i < 10 do
    i = i + 1
end

Like the if-then-else block, you do not need parenthesis around the test expression. The do and end keywords are required.

It is important for the test condition to use a variable that is modified inside the loop block. If the test always evaluates to true, then the loop will run forever.

Repeat

A repeat loop is like a while loop, but the test occurs at the end of the block. The loop will run again if the test condition is false.

repeat
    local char = io.read(1)
    line = line .. char
until char == '\n'

The keywords do and end are not used. Because the test occurs at the end of the block, you can use variables that are local to the block. Of course, those variables cannot be used after the until statement. Like a while loop, a repeat loop will run forever if the test condition never changes.

For with numbers

A for loop repeats a block a certain number of times. The repeat count is calculated once before the loop begins.

n = 0
for i = 1,10 do
    n = n + i
end
print n        -- 55

for i = 2,10,2 do
    print(i)   -- 2,4,6,8,10
end

The first number is assigned to the control variable at the start of the loop. Each time the loop repeats, the value of the variable is incremented. If the value is greater than the second number, then the loop ends. If a third number is given, then the value is incremented by that number. The increment value may be negative, in which case the first number should be greater than the second number. If the numbers are such that the second number cannot be reached by adding the third number to the first, then the loop will not run at all. This means a for loop will always end.

The control variable of a for loop is local to the loop block. Changing the value of the variable inside the block will not affect the loop. Even though the change will be seen inside the block, the loop counter will always assign the next number regardless of what you assigned to the variable.

For with iterator

Iterators are a way of creating dynamic loops. The number of times the loop repeats depends on the result of another function. The loop calls the function and runs the loop if the function does not return nil.

function next(t, i) do
    i = i + 1
    if i > #t then return nil end
    return i, t[i]
end

t = get_table()
for index, name in next,t,0 do
    print(index .. ':' .. name)
end

The three values on the right side of the in keyword are an iterator function, a data value for the iterator, and an initial value for the iterator. At the beginning of the loop, the iterator function is called with the data value and the initial value. The iterator returns at least one value that is assigned to the variables on the left side of the in keyword. These variables are local to the loop block. After the block runs, the iterator function is called again. The first value returned from the previous call is used for the second parameter in the function call. The first parameter is always the data value. So in the example, the function next is called with the parameter i equal to 0, then 1, then 2, etc. The loop ends when the iterator returns nil.

In practice, there are functions which return the three values for the right side of the in keyword together. Using these helper functions makes the for loop easier to write. The ipairs function does the same thing as the previous example’s iterator.

for index, name in ipairs(get_table()) do
    print(index .. ':' .. name)
end

Functions that are designed for this purpose will usually say so in their description.

Break

Sometimes you will want to interrupt a loop block before it ends. The break keyword bypasses the test condition and jumps to the statement following the current loop block.

A limitation of break is that the statement must be at the end of some block. In practice, this isn’t a problem because the interruption usually occurs because of some condition that you have tested for with an if-then-else statement.

a,b = 0,0
while true do
    a = a + 1
    if a >= 10 then
        break
    else
        b = b + a
    end
end
print(a,b)     -- 10, 45

The if-then-else statements create blocks that are sufficient for the break statement. It would be an error if a statement were to appear immediately afterwards. Even though it is in a nested block, it is the outer while loop that is being interrupted. If this while loop were nested inside another loop, then that outermost loop would run uninterrupted by the break statement.

lgscript/lua_blocks.txt · Last modified: 2011/05/15 21:42 by telliamed