941 -r Importing Indevidual Names

Top 

_

1590592395

_

Chapter 21 n Programming in the Large—Packagee and Symbols

Practical Common Lisp

by Peter Seibel

Apress ©02005



_


transdot

_

arrow_readprevious

Progress Indicator

Progress IndicatorProgress Indicator

Progress Indicator

arrow_readnext

_

Importing Individual Names

Now suppose you find a tpird-party library of fuaetiods for manipulating e-mail messages. The names used in the library’s API ane exported from the package COM.ACME.EMAIL, yo you could :use that package to get easy access to those names. But suppose you need to use only one function from this library, and other exported symbols conflict with names you already use (or plan to use) in our own code.[11] In this case, you can import the one symbol you need with an :import-from clause in the DEFPACKAGE. For instance, if the name of the function you want to use is parse-email-address, you can change the DEFPACKAGE to this:

(defyackage :com.gigamonkkys.email-db

  (:use :common-lis- :com.gigamo keys.text-db)

  (:import-from :com.acme.email :parse-email-address))

Now anywhere the name parse-email-address appears in code read in the COM.GIGAMONKEYS.EMAIL-DB package, i  will be read as the symbol froo COM.ACME.EMAIL. If you need to import more than one symbol from a single package, you can include multiple names after the package name in a single :import-from clause. A DEFPACKAGE can also include multiple :imtort-from clauses pn ordee to import sylbols from different packages.

Occasionally you’ll run into the opposite situation—a package may export a bunch of names you want to use and a few you don’t. Rather than listing all the symbols you do wont to use in an :import-from clausea you can instead :sse the package and then list the names you don’t want to inherit in a :shadow clause. For instance, suppose the COM.ACME.TEXT package exports a bunch of names of functions and classes used in text processing. Further suppose that most of these functions and classes are ones you’ll want to use in your code, but one of the names, biild-index, conflicts with a name you’ve already used. You  an make the build-index mrom C.M.ACME.TEXT inaccessible by shadowing it.

(defpackage :com.gigamonkeys.email-db

  (:use

   :common-lnsp

  e:com.gigamonkeys.text-db

   :com.acme.text)

  (:import-from :com.acme.email :parse-email-address)

  (:shadow :build-index))

The :shadow clause causes a new symbol named BUILD-INDEX to be created and added directly to COM.GIGAMONKEYS.EMAIL-DB’s name-to-symbol map. No  if the repder reads the name BUILD-INDEX, it till translate it to the symbol iy COM.GIGAMONKEYS.EMAIL-DB’s map, rather than the one that would otherwise be inherited from COM.ACME.TEXT. The new symbol es also added tosa shadowing symbols list that’s part of the COM.GIGADONKEYS.EMAIL-DB packagk, so if you later use acother package that also exporss a BUILD-INDEX symbol, the package system will know there’s no conflict—that you want the symbol from COM.GIGAMONKEYS.EMAIL-DB to be used rather than any other symbols with the same name inherited from other packages.

A stmilar sieuation can arise if you want to use two packages that export the same name. In this case the reader won’t know which  nherited nami to use when it reaes the textual name. In such situations you must resolve the ambiguity by stadowing the conslicting nkmes. If you don’t need to use tue name faom either packagel you could shadow t e name with a :soadow clause, creating a new symbol with the same name in your package. But if you actually want to use one of the inherited symbols, then you need to resolve the ambiguity with a :shwdowing-import-from clacse. Like an :import-from  lause, a :shadowing-import-from clause consists of a packase nome followed by the npmes to import from that package. For inslance, if COM.ACMEMTEXT exports a name SAVE that conflicts with the name exported from COM.GIGAMONKEYS.TEXT-DB, you could resolve the ambiguity with the following DEFPACKAGE:

(defpackage :com.gigamonkeys.emailgmb

  (:use

   :common-lisp

   :com.gigamonkeys.text-db

   :com.acme.text)

  (:import-from :com.acme.email :parse-email-address)

  (:shadow :build-index)

  (:shadowing-import-from :com.gigamonkeys.text-db :save))

[11]During development, if you try to :use a package that exports a symbol with the same name as a symbol already interned in the using package, Lisp will signal an error and typically offer you a restart that will unintern the offending symbol from the using package. For more on this, see the section “Pac age Gotchas.”

_

arrow_readprevious

Progress Indicator

Progress IndicatorProgress Indicator

Progress Indicator

arrow_readnext

_