0

I am looking at a situation where I'd like to bring some structure to what would be a string in an typical language. And wondering how to use Rebol's parts box to do it.

So let's say I've got a line that looks like this in the original language I'm trying to dialect:

something = ("/foo/mumble" "/foo/${BAR}/baz")

I want to use Rebol's primitives, so certainly a file path. Here is a random example of what I thought of off the top of my head:

something: [%/foo/mumble [%/foo/ BAR %/baz]]

If it were code you'd use REJOIN or COMBINE. But this is not designed to be executed, it's more like a configuration file. You're not supposed to be running arbitrary code, just getting a list of files.

I'm not sure about how feasible it is to stick with strings and yet still have these type as FILE!. Not all characters work in a FILE!, for instance:

>> load "%/foo/${BAR}/baz"
== [%/foo/$ "BAR" /baz]

It makes me wonder what my options are in Rebol data that's supposed to represent a configuration file. I can use plain old strings and do substitutions like other things do. Maybe REWORD with an OBJECT block to represent the environment?

What is the 'reword' function in Rebol and how do I use it?

In any case, I want to know how to represent a filename in a declarative context with environment variable substitutions like this.

Community
  • 1
  • 1

2 Answers2

3

I should use file! Your example need "" after %

f: load {%"/foo/${BAR}/baz"}

replace f "${BAR}" "MYVALUE" ;== %/foo/MYVALUE/baz

hussic
  • 1,816
  • 9
  • 10
2

you could use path! with parens.

the only issue is the root, for which you can use another character to replace the "%" used for files... let's use '! (note this should be a word 'valid character).

when calling to-block on a path! type, it returns each part as its own token... useful.

to-block '!/path/(foo)/file.txt
== [! path (foo) file.txt]

here is a little script which loads three paths and uses parens as a constructed part of the path and uses tags to escape path-illegal characters (like a space!)

environments: make object! [
    foo: "FU"
    bar: "BR"
]

paths: [
    !/path/(foo)/file.txt
    !/root/<escape weird chars $>/(bar ".txt")
    !/("__" foo)/path/(bar)
]

parse paths [
    some [
        (print "------" )       
        set data  path! here: ( insert/only here to-block data to-block data )
        (out-path: copy %"" )
        into [
            path-parts: (?? path-parts)
            '! 
            some [
                  [ set data [word! | tag! | number!] (
                    append out-path rejoin ["/" to-string data]
                  )]
                | 
                into [
                    ( append out-path "/")
                    some [
                          set data word! ( append out-path rejoin [to-string get in environments data] )
                        | set data skip ( append out-path rejoin [ to-string data])
                    ]
                ]
                | here: set data skip (to-error rejoin ["invalid path token (" type? data ") here: " mold here])
            ]
        ]
        (?? out-path)
    ]
]

Note this works both in Rebol3 and Rebol2

output is as follows:

------
path-parts: [! path (foo) file.txt]
out-path: %/path/FU/file.txt
------
path-parts: [! root <escape weird chars $> (bar ".txt")]
out-path: %/root/escape%20weird%20chars%20$/BR.txt
------
path-parts: [! ("__" foo) path (bar)]
out-path: %/__FU/path/BR
------
moliad
  • 1,503
  • 8
  • 13
  • There are MANY more things I could have added, but I wanted to keep the example short and to reply to your question as directly as possible... it covers all four of your tags directly :-) – moliad Oct 03 '14 at 01:38
  • It's an interesting idea, but it only solves the case for an environment variable which occupies a whole path subsection. People sort of expect a macro-like facility so they can do like **"/foo/bar/${FIRST}_${LAST}/baz"** where the two substitutions are glued together to make directory name that has two parts separated by an underscore. The bit about not being able to use an empty file as the start of a paren path is one of those things I wonder if new spacing rules could (or should) cover; like **(a)/b/c** getting fixed. – HostileFork says dont trust SE Oct 03 '14 at 01:44
  • Oh, missed the detail because I generally am skeptical of the idea conceptually. It's like these path segment boundaries are always implicitly involving a slash...so any escaped weird characters with tag or sequences in a paren will have slashes before and after them. It sort of forces you to pick your modality for each piece of the path. I'll think on it. There are a lot of things that do have this character, I don't know if it would wind up seeming wonky or clean things up? :-/ – HostileFork says dont trust SE Oct 03 '14 at 01:57
  • sorry, editing my comment forced me to delete it and put it back here... look at the output... the last path has "__" in the parens where it is added directly to the output... basically, the parens allow you to construct a path part using multiple tokens and values. Your example would be this path: `!/foo/bar/(FIRST "_" LAST)/baz` – moliad Oct 03 '14 at 01:58
  • It definitely would confuse people saying `!/foo/(bar)/<1.txt>` Like "why did I have to put 1.txt in angle brackets, I didn't for a.txt..." – HostileFork says dont trust SE Oct 03 '14 at 02:00
  • yep... not perfect. sometimes, the easiest is to build a string parser and choose a string type to parse it from... like putting your path inside a tag! or prefixing the string with a one letter word, like I used '! above. ex: `!"/foo/__(bar)/1.txt"` – moliad Oct 03 '14 at 02:11