Search code examples
shellfactor-lang

How Can I Persist a Change Directory Outside of a Shell Script In Factor?


I have the following factor code in a file:

IN: set-work-dir
USING: shell ;
CONSTANT: work-dir "/code" ! I also tried "c:/code" and "c:\\code"--same error
work-dir cd 

When I attempt to run the script from factor I get this error:

C:\>/usr/bin/factor/factor /usr/bin/factor/work/set-work-dir.factor
Generic word absolute-path does not define a method for the fixnum class.
Dispatching on object: 47
(U) Quotation: [ c-to-factor => ]
    Word: c-to-factor
(U) Quotation: [ [ (get-catchstack) push ] dip call => (get-catchstack) pop* ]
(O) Word: command-line-startup
(O) Word: run-script
(O) Word: set-current-directory
(O) Method: M\ object absolute-path
(O) Word: no-method
(O) Method: M\ object throw
(U) Quotation: [
        OBJ-CURRENT-THREAD special-object error-thread set-global
        current-continuation => error-continuation set-global
        [ original-error set-global ] [ rethrow ] bi
    ]

I can get this to run if instead of USING: shell ; I have USING: io.files.private but the directory change isn't preserved outside of the running of the script. I'm assuming using shell will cause the directory change to persist--which I realize may be a bad assumption. How can I write a script to change the directory and have the directory change persist outside of the script?

Windows 7 (Yes, I know the dir separator on Windows is usually \ and I tried '\' too. But / actually works on Windows too. Besides the path works when I use io.files.private).

Factor 0.98 x86.64 (1788, heads/master-e187d63d3c, Tue Oct 18 02:14:22 2016) [Microsoft Visual C++ 190023506] on windows


Solution

  • The cd work exists in two vocabs. Which one cd will call depends on what you are USING:. If shell then shell:cd is called if io.files.private then io.files.private:cd is called. You can of course use the fully qualified name too.

    Though the io.files.private:cd word shouldn't be used by user code because the vocab's name ends with .private which indicates that the word isn't part of the public interface. Instead use set-current-directory:

    IN: scratchpad "/tmp" set-current-directory
    IN: scratchpad "." absolute-path .
    "/tmp"
    

    The change will not persist after the Factor process terminates.