Книга: Learning GNU Emacs, 3rd Edition

11.2.1 Statement Blocks

11.2.1 Statement Blocks

We have seen that a statement block can be defined using the let function. We also saw that while and save-excursion include statement blocks. Other important constructs also define statement blocks: progn and other forms of let.

progn, the most basic, has the form:

(progn
  statement-block)

progn is a simple way of making a block of statements look like a single one, somewhat like the curly braces of Java or the begin and end of Pascal. The value returned by progn is the value returned by the last statement in the block. progn is especially useful with control structures like if (see the following discussion) that, unlike while, do not include statement blocks.

The let function has other forms as well. The simplest is:

(let (var1 var2...)
  statement-block)

In this case, instead of a list of (var value) pairs, there is simply a list of variable names. As with the other form of let, these become local variables accessible in the statement block. However, instead of initializing them to given values, they are all just initialized to nil. You can actually mix both forms within the same let statement, for example:

(let (var1 (var2 value2) var3 ...)
  statement-block)

In the form of let we saw first, the initial values for the local variables can be function calls (remember that all functions return values). All such functions are evaluated before any values are assigned to variables. However, there may be cases in which you want the values of some local variables to be available for computing the values of others. This is where let*, the final version of let, comes in. let* steps through its assignments in order, assigning each local variable a value before moving on to the next.

For example, let's say we want to write a function goto-percent that allows you to go to a place in the current buffer expressed as a percentage of the text in the buffer. Here is one way to write this function:

(defun goto-percent (pct)
  (interactive "nGoto percent: ")
  (let* ((size (point-max))
        (charpos (/ (* size pct) 100)))
    (goto-char charpos)))

As we saw earlier, the interactive function is used to prompt users for values of arguments. In this case, it prompts for the integer value of the argument pct. Then the let* function initializes size to the size of the buffer in characters, then uses that value to compute the character position charpos that is pct (percent) of the buffer's size. Finally, the call of goto-char causes point to be moved to that character position in the current window.

The important thing to notice is that if we had used let instead of let*, the value of size would not be available when computing the value of charpos. let* can also be used in the (var1 var2 ...) format, just like let, but there wouldn't be any point in doing so.

We should also note that a more efficient way to write goto-percent is this:

(defun goto-percent (pct)
  (interactive "nPercent: ")
  (goto-char (/ (* pct (point-max)) 100)))

Оглавление книги

Оглавление статьи/книги

Генерация: 1.852. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз