Page 96      All Pages  All Books
my $rand = $seed; return sub {
# Compute a new pseudo-random number based on its old value
# This number is constrained between 0 and 1000. $rand = ($rand*21+1)%1000;
}; }
We can now use mysrand as many times as we want and get back completely independent closures, each capable of generating random numbers from its own starting point:
$random_iter1 = my_srand (100); $random_iter2 = my_srand (1099); for ($i = 0; $i < 100; $i++) {
print $random_iter1(), " ", $random_iter2(), "\n"; }
4.4.3 Closures Versus Objects
If you don't have a background in object orientation, you might be able to understand this section better after you have read Section 7.2, "Objects in Perl".
An object, to give the street definition, is a package of data and functions. The data provides the context for the object's functions to work properly. When you say, for example, $button->setForeground("yellow"), the setForeground function automatically knows which button you are talking about.
In a sense, the facility for closures attempts the same feature - it is also a binding between a subroutine and some private data that is available only to that subroutine. As we saw earlier, in the even_odd_print_gen example, there can be any number of subroutines that can refer to the same basic data, as long as they were all created in exactly the same scope. Abelson, Sussman, and Sussman's delightful Structure and Interpretation of Computer Programs [3] illustrates how to create and use such objects in Scheme (a LISP dialect).
Perl supports a number of features for object orientation (such as inheritance and virtual functions à la C++) that make it easier to create iterators and streams in an object-oriented style than by using closures (the object's attributes reflect the "state" of the iterator). Closures are also much more space-intensive than objects but a trifle faster; we will study the reason for this in Chapter 20.
I prefer objects to closures in all cases except one: callback procedures. I find it easier to implement callbacks with simple closures than to create "callback objects," as you might typically do in C++ (and have to, in Java). In the CreateButton example above, you could create a callback object with exactly one "method," say, execute(). The button would call the method $callback_object->execute() when it was clicked upon, and the execute method of that object would know exactly what to do. The callback object can store all the context for execute to work. Instead of all this work, it is simpler and more direct to use closures, because they automatically squirrel away the required context.
Tom Christiansen's perltoot document (toot stands for Tom's Object-Oriented Tutorial [2]) implements objects using closures to represent the objects' state. It is an interesting approach, but I don't use it because

Page 96      All Pages  All Books