Hi Fantam,

you're shooting yourself in the foot.

1. The solution

>> list-dirs: func [ dir [file!] "root dir" /local dirtree ] [
[     if count = 0 [dirtree: make block! 100]
[     count: count + 1
[     print ["Count: " count "type? dirtree" type? dirtree]
[     foreach name read dir [
[         if dir? dir/:name [
[              append dirtree dir/:name
[              list-dirs dir/:name
[             ]
[         ]
[     dirtree
[    ]
>>
>> list-dirs %.
Count:  1 type? dirtree block
Count:  2 type? dirtree none
** Script Error: append expected series argument of type: series port.
** Where: append dirtree dir/:name
list-dirs dir/:name

I modified your function slightly. Most importantly I added a print
statement before the foreach loop:


    print ["Count: " count "type? dirtree" type? dirtree]

As you can see this print statement reports that upon the first recursive
call of list-dirs (count = 2), dirtree is set to none, it is not a block:

>> list-dirs %.
Count:  1 type? dirtree block
Count:  2 type? dirtree none

Therefore you get an error message, complaining that REBOL cannot append to
a none value:
** Script Error: append expected series argument of type: series port.
** Where: append dirtree dir/:name

a) By making count a global word and setting its value to 1 in list-dirs,
you are preventing dirtree from being set to a block value each time
list-dirs is called.

b) By making dirtree a local word you force it to be initialized to none at
each call to list-dirs, also during recursive calls.

So, when list-dirs is entered recursively, dirtree is set to none by REBOL,
because it is declared a local word (the [block!] expression behind the
word does not have any effect, this notation is only effective for
parameters, but not for local words), count was previously set to 1, and
therefore dirtree is not being set to a block. That generates the error
message documented above.


2. A few points

you wrote:

>script will throw an error

1. Note what REBOL reports as an error. Sometimes that information can be
helpful!

>when it encounters a directory that has a dot in its name (for
>example, "temp.old"). Furthermore, the error is thrown only if that
>directory is a second level sub-directory of the argument (for example
>"%/c/temp/temp1/temp.old" and not "%/c/temp/temp.old").

2. Does the following code work?

>> x: []
>> name: %a.b/
>> dir: %c/d/e.f/
>> append x dir/:name
== [%c/d/e.f/a.b/]

>The most confusing thing is that if I remove the local definition of
>'dirtree in the func spec, 

3. What's the [block!] doing after dirtree?

>> f: func [/local dirtree [block!]] [ print type? dirtree]
>> f
none

It certainly has no influence on the type of dirtree!


Hope this helps,

;- Elan [ : - ) ]
    author of REBOL: THE OFFICIAL GUIDE
    REBOL Press: The Official Source for REBOL Books
    http://www.REBOLpress.com
    visit me at http://www.TechScribe.com


Reply via email to