[asdf-devel] ASDF2: Please, no unwrapped calls to "truename".

Jean-Claude Beaudoin jean.claude.beaudoin at gmail.com
Mon Apr 5 16:38:47 UTC 2010


Robert Goldman wrote:
> On 4/5/10 Apr 5 -6:38 AM, Jean-Claude Beaudoin wrote:
>> My very first attempt at using ASDF version 1.661 on my system
>> ended-up in the debugger on a file-error signaled by
...
>> I fixed the situation by modifying asdf::component-parent-pathname
>> this way:
>>
>> (defun component-parent-pathname (component)
>>    (aif (component-parent component)
>>         (component-pathname it)
>>         (or (ignore-errors (truename *default-pathname-defaults*))
>> 	     *default-pathname-defaults*)))
> 
> Can you explain why ignore-errors is correct here?  Seems like that OR
> there is just hoping that something good will happen even if TRUENAME
> raises an error.  Why is it better to quash an error and hope, instead
> of bringing the error to the user's attention?

Well, ignore-errors as used here is "correct" if one understands
"correct" to mean "good enough" and not "the superior and exact solution".
In that I merely followed the usage of all other calls to truename
inside asdf.lisp. My thinking being that thus I was not introducing
any new policy with respect to this element.  Also, the code here above
is a return to the status quo ante, in old ASDF component-parent-pathname
was happy to return *default-pathname-defaults* directly, without any
processing through truename.  If it worked back in ASDF 1 it is probably
not too bad a fallback plan in ASDF2.

Some other form of wrapping, a handler-case of some kind, could also do.
It is the unwrapped use of (truename *default-pathname-defaults*) that
is problematic, ignore-errors is just one form of wrapping (the quick
and easy one).

> 
> I'm willing to believe that there IS a reason, but will you please
> explain what it is?  For example, what was the case you encountered, and
> why would it have been better to return *default-pathname-defaults*
> instead of raising an error?  What were the *default-pathname-defaults*
> in this case?

There is no guarantee that the content of *default-pathname-defaults*
is suitable for truename at all times. Being a global variable its value
could be changed by any other thread unless pain is taken to rebind it
locally to some value assured reasonable. One could simply do
(setq *default-pathname-defaults* (make-pathname :type "fas")) and
have every following evaluation of (truename *default-pathname-defaults*)
signal a condition.

No matter the precise value of *default-pathname-defaults*, any unwrapped
(truename *default-pathname-defaults*) is pretty much the equivalent
of a booby-trap waiting to explode.

In my specific case *default-pathname-defaults* had value #P"" and on
my system (truename #P"") is a sure way to get a condition signaled.
Now you could argue that most current CL would evaluate (truename #P"")
to the pathname of the current working directory. In my view that
behavior of truename is a pretty liberal reading of the space between
the lines of the ANSI CL standard. I may have to change that behavior
to make it closer to what seems to have now achieved the status
of more or less de facto tradition, but that is beyond the matter
of my original post.

> 
> My philosophy is more "signal errors strictly and as early as possible"
> than "protect your users from errors in cases of bad data."
> 

The net result I got when I tried (asdf:load-system :cffi) was
an invocation of the debugger telling me that #P"" could not be found
in the file system. If one wants to send casual users running for
the door to never return one could hardly do better. Signaling
an error to the user on this matter would require a lot more
context information in order to make it in any way meaningful.
And that could only be achieved by wrapping the offending call
in some condition handler that would latter signal another
augmented condition of its own. And thus I rest my case.

> 
> Thank you,
> 
> Robert





More information about the asdf-devel mailing list