Perl 6具有出色的内置命令行解析功能MAIN.但是,我遇到了一个似乎微不足道的问题,但我无法弄清楚.
一个简单的MAIN:
sub MAIN(Int :n(:$num)) {
say "You passed: " ~ $num;
}
Run Code Online (Sandbox Code Playgroud)
然后我可以将我的脚本称为:
$ ./test.p6 -n=1
Run Code Online (Sandbox Code Playgroud)
要么:
$ ./test.p6 --num=1
Run Code Online (Sandbox Code Playgroud)
但不能用:
$ ./test.p6 -n 1 # or even -n1
Run Code Online (Sandbox Code Playgroud)
要么:
$ ./test.p6 --num 1
Run Code Online (Sandbox Code Playgroud)
perl从命令行运行单行具有安全隐患.
问题是选项-n/-p触发菱形运算符<>,它使用两个参数形式open,因此文件名包含特殊字符,perl不能按预期工作:
$ perl -pe '' 'uname|'
Linux
Run Code Online (Sandbox Code Playgroud)
或者当文件名开头时更危险>,比如>file.在这种情况下,文件将被截断.
要解决此问题,我们可以:
ARGV::readonly通过自己实现模块之类的功能:perl -pe 'BEGIN{$_.="\0" for @ARGV} ...' ./*
Run Code Online (Sandbox Code Playgroud)
-i选项,perl在处理之前检查文件是否存在.-T选项启用污染模式.我认为所有解决方案都可以解决这个问题,但也会产生副作用.如果我们可以强制perl总是使用open它的论证形式,那将是一个更好的解决方案.
我想我们可以做到这一点,强制perl总是使用你的论证形式open?
注意
这个问题仅适用于perl从命令行运行一个内联的情况,因为(当然)我们总是可以open在Perl脚本中使用三个参数形式.
File::Find::Closure从这里读取模块的源代码,我无法理解这些行的目的:
package File::Find::Closures;
use strict;
use warnings;
no warnings;
Run Code Online (Sandbox Code Playgroud)
warnings打开后模块中是否有某些东西无法关闭?使用Python 3,dis.dis()可以很好地解析字符串包含for循环语法:
>>> import dis
>>> dis.dis('for _ in range(10): pass')
1 0 SETUP_LOOP 20 (to 23)
3 LOAD_NAME 0 (range)
6 LOAD_CONST 0 (10)
9 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
12 GET_ITER
>> 13 FOR_ITER 6 (to 22)
16 STORE_NAME 1 (_)
19 JUMP_ABSOLUTE 13
>> 22 POP_BLOCK
>> 23 LOAD_CONST 1 (None)
26 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
在Python 2中,它产生了string index out of range错误:
In [30]: dis.dis('for _ in range(10): pass')
---------------------------------------------------------------------------
IndexError Traceback …Run Code Online (Sandbox Code Playgroud)