From: skamboj
Subject: Packaging advice needed
Date: 
Message-ID: <1157747849.670241.40910@i3g2000cwc.googlegroups.com>
Hi All,

I need some help on common-lisp packages.

Let's say, I define a new package for all my code, as follows:

(defpackage my-package
            (:use common-lisp)
            (:export foo))

(in-package :my-package)

And then define a function that reads in some configuration options
from a file, similar to the one given below:

(defun foo (file)
	      (with-open-file (conf-stream file
					   :direction :input
					   :if-does-not-exist :error)
		(let ((conf-info (read conf-stream)))
		  (assoc 'bar conf-info))))

The problem is that the symbols in file will be interned in whatever
package my-package:foo is called from, so the above function will more
often than not return nil.

Is there a simple way of ensuring that my-package:foo will always work
irrespective of the package in which it is called?

Note: I can *NOT* use keywords for the symbols. (Some of the file
contents have to follow a specification that is out of my control).

Any suggestion will be greatly appreciated. 

Thanks,
Sachin.

From: Benjamin Tovar
Subject: Re: Packaging advice needed
Date: 
Message-ID: <87fyf2yst2.fsf@the.google.mail.thing>
"skamboj" <·······@gmail.com> writes:

> 		(let ((conf-info (read conf-stream)))
> 		  (assoc 'bar conf-info))))
>
> The problem is that the symbols in file will be interned in whatever
> package my-package:foo is called from, so the above function will more
> often than not return nil.
>
> Is there a simple way of ensuring that my-package:foo will always work
> irrespective of the package in which it is called?

You may use 

(assoc "bar" conf-info 
                  :test #'equal 
                  :key  #'(lambda (x) (symbol-name x)))


Benjamin

-- 
"Master your instrument, master the music, and then forget all that
bullshit and just play." -- Charlie Parker
From: Lars Brinkhoff
Subject: Re: Packaging advice needed
Date: 
Message-ID: <85bqpmwnfk.fsf@junk.nocrew.org>
Benjamin Tovar <······················@the.google.mail.thing> writes:
>> Is there a simple way of ensuring that my-package:foo will always work
>> irrespective of the package in which it is called?
> You may use 
> (assoc "bar" conf-info 
>        :test #'equal 
>        :key  #'(lambda (x) (symbol-name x)))

Or (assoc "bar" conf-info :test #'string=)
From: Benjamin Tovar
Subject: Re: Packaging advice needed
Date: 
Message-ID: <87irjuxqu5.fsf@cayita.neverwhere.net>
Lars Brinkhoff <·········@nocrew.org> writes:
>> (assoc "bar" conf-info 
>>        :test #'equal 
>>        :key  #'(lambda (x) (symbol-name x)))
>
> Or (assoc "bar" conf-info :test #'string=)

Thanks for the tip.

Benjamin


-- 
"Master your instrument, master the music, and then forget all that
bullshit and just play." -- Charlie Parker
From: Pascal Costanza
Subject: Re: Packaging advice needed
Date: 
Message-ID: <4me454F5ovuiU5@individual.net>
skamboj wrote:
> Hi All,
> 
> I need some help on common-lisp packages.
> 
> Let's say, I define a new package for all my code, as follows:
> 
> (defpackage my-package
>             (:use common-lisp)
>             (:export foo))
> 
> (in-package :my-package)
> 
> And then define a function that reads in some configuration options
> from a file, similar to the one given below:
> 
> (defun foo (file)
> 	      (with-open-file (conf-stream file
> 					   :direction :input
> 					   :if-does-not-exist :error)
> 		(let ((conf-info (read conf-stream)))
> 		  (assoc 'bar conf-info))))
> 
> The problem is that the symbols in file will be interned in whatever
> package my-package:foo is called from, so the above function will more
> often than not return nil.
> 
> Is there a simple way of ensuring that my-package:foo will always work
> irrespective of the package in which it is called?
> 
> Note: I can *NOT* use keywords for the symbols. (Some of the file
> contents have to follow a specification that is out of my control).
> 
> Any suggestion will be greatly appreciated. 

I don't completely understand your problem, but you can simply rebind 
*package* before you call read:

(let ((*package* ... some package ...))
   (read ...))

Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Harald Hanche-Olsen
Subject: Re: Packaging advice needed
Date: 
Message-ID: <pcowt8e12bp.fsf@shuttle.math.ntnu.no>
+ "skamboj" <·······@gmail.com>:

| Let's say, I define a new package for all my code, as follows:
|
| (defpackage my-package
|             (:use common-lisp)
|             (:export foo))
|
| (in-package :my-package)
|
| And then define a function that reads in some configuration options
| from a file, similar to the one given below:
|
| (defun foo (file)
| 	      (with-open-file (conf-stream file
| 					   :direction :input
| 					   :if-does-not-exist :error)
| 		(let ((conf-info (read conf-stream)))
| 		  (assoc 'bar conf-info))))
|
| The problem is that the symbols in file will be interned in whatever
| package my-package:foo is called from, so the above function will more
| often than not return nil.
|
| Is there a simple way of ensuring that my-package:foo will always work
| irrespective of the package in which it is called?

One easy way:

(defun foo (file &key ((:package *package*) (find-package :my-package)))
  (with-open-file (conf-stream file
		   :direction :input
		   :if-does-not-exist :error)
    (let ((conf-info (read conf-stream)))
      (assoc 'bar conf-info))))

If you don't care about the extra flexibility of the keyword
parameter, allowing you to specify the package at runtime, just use an
&aux parameter instead.

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- It is undesirable to believe a proposition
  when there is no ground whatsoever for supposing it is true.
  -- Bertrand Russell