-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Restore original path when DO of a script fails #2374
Comments
this is an annoying issue so if we decide to fix it, then great. |
NOTE: this comment applies to changes to the current directory that take place from inside the running script. Please see my further comment below for the real story of this issue! The current directory is part of the process environment, like env-vars, open files, ports, etc. |
@Mark-hi makes a good point—though I'd say as a temporary change of directory is a feature of DO FILE, perhaps—if a failed script can be detected—it should revert unless the current path has been explicitly changed by that script. |
Thank you for mentioning this @rgchris! My apologies to you and @lkppo, I misunderstood this issue report completely. |
No problem. I too have fallen a thousand times in this way. :-)) I was surprised that this bug is also in Rebol 2 (I'm learning the language and Ren-c). Not knowing the whole story I was wondering if the path is the only contextual data affected. |
Technical point to bring into the discussion: the notion of "current directory" bears some scrutiny. For instance: if you But the filesystem runtime (e.g. Windows SetCurrentDirectory() or POSIX chdir()) can't hold a state that's a URL path. Ren-C was changed so that the "current directory" reported by WHAT-DIR is stored in a Rebol system variable. (well, @Mark-hi points out that there was a variable before, but it just was wired in somewhere you won't find in the source to WHAT-DIR in particular). Anyway, it is allowed to be a URL! or a FILE!. However, if you ask WHAT-DIR and it's a file path...it currently re-syncs that independent notion with whatever the filesystem happens to think it is. (If the filesystem "extension" is loaded...which it is not in the web build) I'm not sure what this implies for the notion of rolling things back. But just mentioning it. |
(The following are the meanderings of a mildly addled mind. None of this is canon, or written down anywhere else, yet.) |
In above commit the |
Better late than never when looking at these issues... :-/ TL;DRDO of a script by FILE! or URL!--including scripts invoked on the command line--should not change the working directory. Instead, a different syntax (TAG!) is used to locate resources relative to the executing script. (This replaces a prior convention of using tags to lookup modules by shorthand in the module repository, e.g. RationaleBecause DO takes arguments from its caller, it needs a way of understanding those arguments in context. And when a user passes relative paths in on the command line, those paths are relative to their working notion of what the directory is. Information about the caller's notion of working directory can't be thrown out. And the most straightforward way to preserve the information is simply to not change the directory in the first place. -But- this means a solution is needed for what changing the directory was intended to address: Making it easier for scripts to find resources relative to their own file location. The solution is to use TAG! as a syntax for looking for things relative to Behavior of IMPORTThe IMPORT command is different, because it loads the module only once...and hence it can't make any particular assumptions about the directory it is being called from. This might mean that the current directory should be set to NULL, as a way of preventing misconceptions people might have about the relationship between IMPORT and the script that imports it being 1:1 (For the near term, the current behavior of setting the working directory to that of the module being imported can be left as-is.) Application to Other FunctionsAmong functions that would want to honor this convention would be LOAD. The loading of data and resources has similar issues: a script may wish to load things the client asked it to load, or it may wish to load data that lives relative to wherever it is. Hence a service function will be available for any other loading-oriented function that wants to translate TAG!s or shorthands to actual URL! or FILE! paths. ExampleLet's say you're in this situation on the command line:
Or equivalently, this situation inside the interpreter:
Then the contents of %script.r will be processed as such:
|
As a new rule for Ren-C as a whole, scripts don't change the working directory when invoked from the command line. Instead, the feature of finding resources relative to the script location is done by using TAG! values as the argument to DO, LOAD, IMPORT: metaeducation/rebol-issues#2374 (comment) So long as the note needs changing, this goes ahead and mentions that the whitespace interpreter is being used as a testbed for the UPARSE parser that is written entirely in interpreted usermode code, and is thus glacially slow compared to native code. The native code rewrite is being held off until a working stream parsing design has been achieved.
DO doesn't restore the original path if code being executed in a subfolder fails. This seems inconsistent.
It can be improved by trapping the error, restore the path and propagate the error to the caller.
This bug can be reproduced by creating a buggy script in a subfolder and launching it from a rebol interpreter where the current path is not the subfolder of the buggy script.
>> pwd
you will get something like== %mytopfolder/
>> do %subfolder/myscript.r
the buggy script will raise an error>> pwd
gives== %mytopfolder/subfolder/
Now the current directory is the subfolder because the script crashed. The context of execution is not restored.
Maybe other things need also to be restored on recovery.
The text was updated successfully, but these errors were encountered: