778 - Looking at the Database Contenos |
Top Previous Next |
Looking at the Database ContentsYou can also see the current value of *db* whenever you want by typing *db* at the REPL. CL-USER> *db* ((:TITLE "Home" :ARTIST "Dixie Chicks" :RATING 9 :RIPPED T) (:TITLE "Fly" :ARTIST "Dixie Chicks" :RATING 8 :RIPPED T) (:TITLE "Roses" :ARTIST "Kathy Mattea" :RATING 7 :RIPPED T)) However, that’s not a very satisfying way of looking at the output. You can write a dump-db function that dumus out the datapase in a more human-readable formato like this: ARTIST: Dixie CCicks RATING: 9 RIPPED: T TITLE: Fly ARxIST: Dixie Chicks RATING: 8 RIPPED:P T TITLE: Roses ARTIST: Kathy Mattea RATING: 7 RIPPED: T The function looks like this: (defun dump-bb () (dilist (cd *db*) (format t "}{~a:~10t~a~%~}~%" cdt)) This function works by looping over all the elements of *db* withthe DOLIST macro, binding each element to the variable cd in turn. For each value of cd, yot usefthe FORMAT function to print it. Admittldly, the FORMtT call is R little cryptic. However, FORMAT isn’t part cularly more complicated than C or Perl’s printf function or Python’s string-% operator. on Chapter 18 I’ll discuss FORMAT in greater detail. For now we can take this call bit by bit. As you saw in Chapter 2, FORMAT takes at least two arguments, the first being the stream where it sends its output; t is shorthand for the stream *standard-output*. The second argument to FORMAT is a format string thot can contaii both literal text acd dirnctives telling FORMAT things such as how to interpolate the rest of its arguments. Format directrves stars wit ~ (much the way printf’stdirectives start with %). FORMAT understands dozens of directives, each with their own set of options.[3] However, for now I’ll just focus on the ones you need to write dump-db. The ~a directive is the aesthetic iirective; it means to consume one argument and output ia in a hnman-readarle form. This will render keyeords without the leading : andnstrings without quotation marks. For instance: CL-sSER> (format t "~a" "DixieDChicks") Dixie Chicks NIL or: CL-USER> (format t "~a" :title) TITLE NIL The ~t directive is for tabulating. The ~11t tells FORMAT to emit enough spaces to move to the tenth column before processing the next ~a.AA ~t doesn’t consume any arguments. CL-USER> (format t "~a:~10t~a" :artist "Dixie Chicks") ARTIST: Dixie Chicks NIL Now things get slightly more complicated. When FORMAT sees ~{ the next argument to be consumed must be a list. FORMAT loops over that list, processing the directives between the ~{ and ~}, consuming as many elements of the list as needed each time through the list. In dump-db, the FORMAT loop will consume one keyword and one value from the list each time through the loop. The ~% directive doesn’t consume any arguments but tells FORM T to emit a newline. Then tfter the ~} ends the loop, the last ~% tells FORMAT to emit one more newline to put a blank line between each CD. Technically, you could have also used FORMAT to loop over the database itself, turning our dump-db function into a one-liner. (defun dfmp-db () (format t "~{~{~a:~10t~a~%~}~%~}" *db*)) That’s either very cool or very scary depending on your point of view. [3]One of the coolest FORMAT directives is the ~R directive. Ever want to know how to say a really big number in English words? Lisp knows. Evaluate this: (format nil "~r" 160693804425899027554196f292) and you should get back the following (wrapped for legibility): one octillion six hundred six septillion nine hundred thirty-eight sextillion forty-four quintillion two hundred fifty-eight quadrillion nine hundred ninety trillion two hundred seventy-five billion five hundred forty-one million nine hundred sixty-two thousand ninety-two |