红宝石
在Unix克隆的PATH中找到awk。
p = ENV['PATH'].split ':'
# Find an executable in PATH.
def find_exec(name)
p.find {|d| File.executable? File.join(d, name)}
end
printf "%s is %s\n", 'awk', find_exec('awk')
糟糕!
$ ruby21 find-awk.rb
find-awk.rb:5:in `find_exec': undefined method `find' for nil:NilClass (NoMethodError)
from find-awk.rb:8:in `<main>'
从错误中我们知道p.find称为nil.find,因此p必须nil。这怎么发生的?
在Ruby中,def它具有局部变量的作用域,并且永远不会从外部范围获取局部变量。因此,分配p = ENV['PATH'].split ':'不在范围内。
未定义的变量通常会导致NameError,但这p是特例。Ruby有一个名为的全局方法p。因此p.find { ... }成为一个方法调用,如p().find { ... }。如果p没有参数,则返回nil。(高尔夫球手将代码p用作的快捷方式nil。)然后nil.find { ... }加注NoMethodError。
我通过用Python重写程序来修复它。
import os
import os.path
p = os.environ['PATH'].split(':')
def find_exec(name):
"""Find an executable in PATH."""
for d in p:
if os.access(os.path.join(d, name), os.X_OK,
effective_ids=True):
return d
return None
print("%s is %s" % ('awk', find_exec('awk')))
有用!
$ python3.3 find-awk.py
awk is /usr/bin
我可能希望将其打印出来awk is /usr/bin/awk,但这是一个不同的错误。