在这里非常适合使用表这种数据结构。reveal() 中的表有两个 slot:一个用于文件,另一个用于目录。filetype( name ) 函数的返回值 — 常量 FILE 或常量 DIR — 将文件系统中的每一项整理到相应的 slot 中。
此外,每个 slot 是一个数组,由 tally[FILE] <- [] 和 tally[DIR] <- []; 这两条语句创建。([] 是一个空数组)。由于 tally 是函数内的本地变量,它将在每次调用时重新创建并清空范围,并且在每个调用被返回时自动销毁。
数组函数 append( arg ) 将 arg 添加到数组的末尾,从而在此过程中形成了一个列表。在执行完 foreach( index, name in names ) 循环后,所有项都被添加到这两个 slot 中其中一个的列表中。函数其余部分的代码将输出文件,接着输出目录,然后是递归。
当然,如果没有命令行参数的话,shell 脚本的价值就没有那么大了。特殊 Squirrel Shell 变量 __argc 和 __argv 分别以字符串数组形式包含命令行参数的计数和参数列表。根据约定,__argv[0] 始终都作为 shell 脚本的名称;因此,如果 __argc 的值至少为 2,那么将提供额外的参数。为了简单起见,这个脚本只处理第一个额外参数 argv[1]。
作为参考,清单 4 展示了一个 Ruby 脚本(作者为 Mr. Makshin),此脚本的功能与清单 3 相同。即使该脚本已像 Ruby 那样简洁,但它在简洁性方面仍然逊色于 Squirrel Shell 代码。
清单 4. 使用 Ruby 重新实现清单 3
!/usr/bin/ruby
# List Directory contents.
path = ARGV[0] == nil ? "." : ARGV[0].dup
# Remove trailing slashes
while path =~ //$/
path.chop!
end
entrIEs = Dir.open(path)
for entry in entries
unless entry == "." || entry == ".."
filePath = "#{path}/#{entry}"
fileStat = File.stat(filePath)
if fileStat.directory?
puts "dir : #{filePath}"
elsif fileStat.file?
puts "file: #{filePath}"
end
end
end
entries.close()
标签: