Search code examples
rebolred-lang

Change file paths


I want to change [%a/b] to [%a/c]. Basically, the same as Change path or refinement, but with file! instead:

I want to change the a/b inside a block to a/c

test: [a/b]

In this case, either change next test/1 'c or test/1/2: 'c works. But not when test is a file!:

>> test: [%a/b]
== [%a/b]
>> test/1
== %a/b
>> test/1/2         ; can't access 2nd value
== %a/b/2
>> next first test  ; not quite what you expect
== %/b

Trying to change it gives not something you'd expect:

>> change next test/1 'c
== %b
>> test
== [%acb]

Solution

  • You are confusing path! and file! series, they can look similar, but their nature are very different.

    A path! is a collection of values (often word! values) separated by a slash symbol, a file! is a collection of char! values. Slash characters in file! series are just characters, so file! has no knowledge about any sub-structures. It has (mostly) the semantics of string! series, while path! has the semantics of a block! series.

    Now that this is cleared, about the test/1/2 result, path notation on a file! series has a different behavior than on string!, it will do a smart concatenation instead of acting as an accessor. It's called smart because it will nicely handle extra slash characters present in left and right parts. For example:

    >> file: %/index.html
    == %/index.html
    
    >> path: %www/
    == %www/
    
    >> path/file
    == %www/file
    
    >> path/:file
    == %www/index.html
    

    Same path notation rule applies to url! series too:

    >> url: http://red-lang.org
    == http://red-lang.org
    
    >> url/index.html
    == http://red-lang.org/index.html
    
    >> file: %/index.html
    == %/index.html
    
    >> url/:file
    == http://red-lang.org/index.html
    

    So for changing the nested content of test: [%a/b], as file! behaves basically as string!, you can use any available method for strings to modify it. For example:

    >> test: [%a/b]
    == [%a/b]
    
    >> change skip test/1 2 %c
    == %""
    
    >> test
    == [%a/c]
    
    >> change next find test/1 slash "d"
    == %""
    
    >> test
    == [%a/d]
    
    >> parse test/1 [thru slash change skip "e"]
    == true
    
    >> test
    == [%a/e]