I see. Thanks.
Also, I thought that when you create a word within the body of a function without
declaring it as local, it would still be local, and not a global one,
as it really is.

daniel
> 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




-- 
Fantam


Reply via email to