My very first attempt at using ASDF version 1.661 on my system ended-up in the debugger on a file-error signaled by function truename.
The offending call came from function asdf::component-parent-pathname that contains a call to truename unwrapped in any condition handler although truename is required to signal errors. This seems to be the only such instance in asdf.lisp, all the other truename calls being wrapped inside a ignore-errors.
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*)))
BTW, I would like to mention that in my CL system *default-pathname-defaults* is not a replacement for the process current working directory (which can be properly queried only through a call to getcwd). Thinking otherwise seems to me to be pretty clearly an unportable assumption unsupported by the ANSI CL standard. That ASDF seems to make that assumption troubles me seriously.
In fact I cannot figure out how I would explain to a naive beginning lisper on MS-Windows that *default-pathname-defaults* is an equivalent of the current directory when there is a potential of up to 26 simultaneous current directories on his OS (one per drive letter).
On the top of that the current working director(y|ies) is/are a process-level attribute and *default-pathname-defaults* being a special variable is most likely to have a thread-local binding at one point or an other, in some CL systems this could even be part of the initial thread bindings. How one reconciles these many independently evolving thread bindings with the single process-level attribute sure beat me!
Cheers,
Jean-Claude Beaudoin
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 function truename.
The offending call came from function asdf::component-parent-pathname that contains a call to truename unwrapped in any condition handler although truename is required to signal errors. This seems to be the only such instance in asdf.lisp, all the other truename calls being wrapped inside a ignore-errors.
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?
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?
My philosophy is more "signal errors strictly and as early as possible" than "protect your users from errors in cases of bad data."
Thank you,
Robert
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
Jean-Claude, I think you made a good point. I committed a fix -- is it satisfactory to you?
[ François-René ÐVB Rideau | Reflection&Cybernethics | http://fare.tunes.org ] Not only is there no contradiction between egoism and altruism, but no altruism is possible without egoism - for what betterment to wish to an other person devoid of selfish desire, to whom any change is indifferent?
On 5 April 2010 17:38, Jean-Claude Beaudoin jean.claude.beaudoin@gmail.com wrote:
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
asdf-devel mailing list asdf-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel
The use of truenamize inside component-parent-pathname seems to work here. I was indeed concerned by the content of resolve-symlinks...
Thank you very much Faré.
Faré wrote:
Jean-Claude, I think you made a good point. I committed a fix -- is it satisfactory to you?
[ François-René ÐVB Rideau | Reflection&Cybernethics | http://fare.tunes.org ] Not only is there no contradiction between egoism and altruism, but no altruism is possible without egoism - for what betterment to wish to an other person devoid of selfish desire, to whom any change is indifferent?
On 5 April 2010 17:38, Jean-Claude Beaudoin jean.claude.beaudoin@gmail.com wrote:
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
asdf-devel mailing list asdf-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel