Members of the Forum -

I've recently been playing with a useful utility I'm calling "climb" because
it climbs a directory tree, doing something at each node.  This "doing
something" is user-specifiable, so this naturally lends itself to an
adverbial construction, to whit:

climb=: 1 : 0
   svdir=. 1!:43 ''
   1!:44 svdir [ rr=. u y [ 1!:44 y
   subds=. ((('d'e.&>4{"1])#0{"1])@:(1!:0@<)) y,'\*.*' NB. Only subdir names
   if. 0~:#subds do. rr=. rr;(u climb)&.>(<y,'\'),&.>subds end.
)

The only very complicated line is the one assigning the subdirectory
variable "subds".  I had originally written this

   subds=. jd dir y,'\*.*' NB. Only subdir names

but have since substituted the definitions for "jd" (just directories) and
"dir" since this makes the function self-contained.

I'm interested in comments on a couple of design choices.  First of all, is
the name good?  The more normal terminology has one "walk" a directory
tree.  In fact, the Rosetta code page "Walk Directory Tree" (
http://rosettacode.org/mw/index.php?title=Walk_Directory_Tree) presents an
application of this code though the problem statement is poorly worded.  It
states that this algorithm will "[w]alk a given directory tree and print
files matching a given pattern" when it apparently means not "print files"
but "display file information", based on the submissions.

Of course, the J function here is more general as it allows one to do
anything while climbing the tree.

Another design choice has us changing directories to run the supplied verb
but it's not clear this is really necessary.

Yet another choice is to make this recursive in order to simplify the
logic.  However, if we were to handle the sub-directory navigation more
explicitly, this opens up the possibility of being able to specify either
"depth-first" or "breadth-first" processing of the tree rather than the
implicit "depth-first" approach of recursion.

Finally, when I first attempted to use this to list files matching a certain
pattern, I had an initial problem specifying my verb.  My first attempt,

   aa=. (dir&'*Bis-B*.csv') climb 'C:\amisc'

failed.  When I examined the behavior of my verb - which intentionally
ignores the default argument inside "climb" of the current directory path -
I found this:
   (dir&'*Bis-B*.csv') 'C:\amisc'
|length error: dir
|       (dir&'*Bis-B*.csv')''

Playing around with some variations led me to this

aa=. ((dir@:])&'*Bis-B*.csv') climb 'C:\amisc'

which worked fine but I'm not clear on why my initial attempt to bind the
right argument of "dir" fails.

In any case, this is a useful utility that offers some room for improvement
but I've already used it successfully in a couple of different ways.

-- 
Devon McCormick, CFA
^me^ at acm.
org is my
preferred e-mail
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to