Getopt::Std 模块

上一篇 / 下一篇  2008-12-08 22:26:26 / 个人分类:perl

  • 文件版本: V1.0
  • 开发商: 本站原创
  • 文件来源: 本地
  • 界面语言: 简体中文
  • 授权方式: 免费
  • 运行平台: Win9X/Win2000/WinXP
  设计程序的用户界面可能很困难而且耗时。Teodor Zlatanov 讨论了如何使用 Parse::RecDescent 模块来用简单的英语创建用户界面文法。他还展示了向程序添加功能或从程序除去功能时,更改文法是如何的方便。另外还与标准的 CLI 解析器和 GUI 进行了比较,讨论了这种方法的优缺点。
1V Q^ e8Q I2v4Z0  51Testing软件测试网_F]6c#N4G4G
  随功能一起发展的很棒的用户界面
#YCt;J1H[x/b0  因为用户界面是程序最初的入口,所以它必须能够用于多种目的。必须向用户提供对程序所有功能的合适访问。在向程序添加更多功能时(这几乎是必然发生的情况),它必须是可扩展的。必须具备灵活性,可以接受常用命令的缩写和快捷方式。它不应该有层叠的菜单或瀑布式单词,这样会让用户感到迷惑。无可否认,以上所有这些要求对程序员来说都是复杂的约束,对此没有一种很好的解决方案能把它们全包括。许多软件产品开发人员到最后再解决用户界面问题,把它作为一种事后来考虑的问题。另外一些开发人员则首先主要考虑用户界面,让功能仅仅成为界面设计选择的结果。这些都不是理想的方法。用户界面(UI)应该随着程序功能的发展而发展,两者就象一枚硬币的正反面。
E d zH4sHS*KO7k0  
Kq!bb3J.VM m0  这里我们将面向解析的方法用于用户界面。虽然这种方法适合于 GUI 界面,但本文不讨论 GUI 设计。我们将专门讨论基于文本的 UI。首先,将简要介绍标准的文本 UI 设计选择,使您能熟悉该环境。然后,将展示 Parse::RecDescent 解决方案,事实证明它是灵活、直观和易于编写的!
gbzkn K c&bNp x0  
4i]+g-oQ0  注:为了运行我们所讨论的某些程序,将需要 Parse::RecDescent CPAN 模块。
2F.Qyz%x&b0  51Testing软件测试网 V jW"^p4Q L
  用传统的 Unix 方式创建的简单用户界面51Testing软件测试网kY1j;q#@S
  Unix 用户非常熟悉基于文本的 UI 模型。设想有一个 Perl 程序,让我们先看一下这个模型用于该程序的简单实现。标准的 Getopt::Std 模块简化了命令行参数的解析。这个程序仅仅为了说明 Getopt::Std 模块(没有实际用途)。请参阅本文后面的参考资料。
G$hh a`y]l0  51Testing软件测试网7z X%B+\%Q!q~.y
  使用 Getopt::Std 的命令行开关
8J7G7Sz7LeI&B0  #!/usr/bin/perl -w
x9N2]D \4r4Gs0  51Testing软件测试网;w;Am-U$eO6JP:i'v
  use strict; # always use strict, it's a good habit
#qQ \9Gf D$EZ$v k0  use Getopt::Std; # see "perldoc Getopt::Std"51Testing软件测试网~!dS5Yq
  51Testing软件测试网#jU(p1Z9a*jm:v6i v
  my %options;
_F-{5^xi0  getopts('f:hl', \%options); # read the options with getopts51Testing软件测试网ib5U;v V'T2U
  51Testing软件测试网e1[6k;JUmf
  # uncomment the following two lines to see what the options hash contains
|_Y*M @ `(x.X0  #use Data::Dumper;51Testing软件测试网4eJ)fi1|W5\;}
  #print Dumper \%options;
"gc*h9A%H^)iN0  51Testing软件测试网3CI'J'GLj,Y YE1yL
  $options{h} && usage(); # the -h switch51Testing软件测试网Iv(mzC5~
  
+cn:z me'Is%i0  # use the -f switch, if it's given, or use a default configuration filename51Testing软件测试网2r.n ~EiO/~
  my $config_file = $options{f} || 'first.conf';51Testing软件测试网A q9\bF6a_ M{
  
#Gu%v u6wB k0  print "Configuration file is $config_file\n";51Testing软件测试网 yH-\p2]B@ W
  
r#@.x`0r1dQ A/n0  # check for the -l switch
9u*Xho(f0  if ($options{l})51Testing软件测试网#i\7_:cyAS
  {
Z3yhTf$p0   system('/bin/ls -l');51Testing软件测试网^i1s$s|&__S
  }51Testing软件测试网k4tmsP`I&u(Sv5l
        else
;`cp&U[t0  {51Testing软件测试网&P&[ Q+J ?y,{7{KN
   system('/bin/ls');51Testing软件测试网-kmi*V8dp q
  }
8\\rQ0v[0i8HJ0  
S*AO"cIh9f-B0  # print out the help and exit51Testing软件测试网Rv(N1][4Ya]` T5?
  sub usage51Testing软件测试网Uo-c/kq e5o
  {51Testing软件测试网6wL'b|3R1h*ac
   print <51Testing软件测试网 Q$Q+h|SI l
  first.pl [-l] [-h] [-f FILENAME]51Testing软件测试网&g#Rcz"O(Y~2L3P.z1g7ZL
  
\@ jE*k!W0  Lists the files in the current directory, using either /bin/ls or
~^&D{aM[0  /bin/ls -l. The -f switch selects a different configuration file.
1^]fo@0k L0  The -h switch prints this help.
8[_4Fvms7]f5o0  EOHIPPUS
WT?+_avJ#?;}0  exit;
K!]xq {/n"[0  }   51Testing软件测试网.X~p6Q[
  51Testing软件测试网 zTx m?w
  简单的事件循环51Testing软件测试网7m4q.^Qac7JPjI
  当命令行参数不够用时,下一步是编写一个事件循环。在这种方案中,仍然可接受命令行参数,并且有时只使用命令行参数就足够了。然而,事件循环支持用户在不输入任何参数的情形下调用程序,以及看到提示符。在此提示符下,通常可使用 help 命令,这将打印出更详细的帮助。有时,这个 help 甚至可以是一个单独的输入提示符,有一个完整的软件子系统来专门负责它。51Testing软件测试网3_RM0A%y X@%|
  
@Sr^/p&Hk0  带有命令行开关的事件循环51Testing软件测试网?Trw2}OE
  #!/usr/bin/perl -w51Testing软件测试网"ic)D,\$Ek#@
  
BX6c[0DY0  use strict; # always use strict, it's a good habit51Testing软件测试网1\8m&E,Ao|VK
  use Getopt::Std; # see "perldoc Getopt::Std"51Testing软件测试网:M6QC:T)uj;Cw
  51Testing软件测试网3aT }.C ip
  my %options;
1j6w$|/p-Ro"k0  getopts('f:hl', \%options); # read the options with getopts
J3H!g:wB"`0  51Testing软件测试网~Jt:t#|s8z+M
  # uncomment the following two lines to see what the options hash contains51Testing软件测试网*Y*A3Bw$hif fx%~
  #use Data::Dumper;51Testing软件测试网7hsH4F U5lc
  #print Dumper \%options;
H+y-u/u,qg0  
t'ZA;gg,V8`} Eh0  $options{h} && usage(1); # the -h switch, with exit option51Testing软件测试网/C"[{hYzo7j5J
  
4kelV,y)p*j)i0  # use the -f switch, if it's given, or use a default configuration filename
#I-]/VJ?w Y6P4DP0  my $config_file = $options{f} || 'first.conf';51Testing软件测试网Jiz\%nV @/y4A'gOD1h
  
Z'n0Zg4U }lvZ0  print "Configuration file is $config_file\n";51Testing软件测试网u2YTg8vq? n8h
  
0jN,Q `s5`XZ`0  # check for the -l switch
RF)T4Md0  if ($options{l})
0|@j1GOVK ^ t0  {
?L cXw:Gu4]8lc'm0   system('/bin/ls -l');
J8D,`,t-i~0  }
[-m_n m3b+K$A*|0        else
%L*\M]"r0  {51Testing软件测试网"a'a6i%vW-Q
   my $input; # a variable to hold user input
W:UJ;@ O0              do {
DV5?kC4G^:y?+E0   print "Type 'help' for help, or 'quit' to quit\n-> ";51Testing软件测试网|.es \6Xf3a#g
   $input = ;
DK$H#z)jmI0   print "You entered $input\n"; # let the user know what we got51Testing软件测试网;C8Tn;LU
  
P&q:Ii|/D0   # note that 'listlong' matches /list/, so listlong has to come first
aLa/ZrA?6Y7T,M+Y|0   # also, the i switch is used so upper/lower case makes no difference
~}`m&T*u9~ Z9C0   if ($input =~ /listlong/i)51Testing软件测试网8H a9x{ cg
   {
&~1T |8A#?|+@0    system('/bin/ls -l');
b)_,@ jQ ToT0   }
@p3K4M T5Wl#D0   elsif ($input =~ /list/i)51Testing软件测试网7E QxO'[1E`
   {51Testing软件测试网U5J:D8@2AU*O/|u
    system('/bin/ls');51Testing软件测试网8e*nAz"Tshl8U
   }
PKQ&v.` x^6R'H0   elsif ($input =~ /help/i)51Testing软件测试网g'o0zl|.D i
   {51Testing软件测试网z,lz CoL#r
    usage();51Testing软件测试网-j(b|8X/~ FxN"i_ W
   }
#Kq/~@a0Yy dp v6O0   elsif ($input =~ /quit/i)51Testing软件测试网 \Yg P)p{ EB
   {
I~ D"tO AS"V4A0    exit;
*Imj[Fq[0   }
%n d_*E&K}0   }
n-acNi$c0   while (1); # only 'quit' or ^C can exit the loop
;N%[&Xgj0  }
Q6y]aj;p9f0  
0r#^B z!xCJ'X._0  exit; # implicit exit here anyway
2x.Xp3C4k:{-xy0  51Testing软件测试网1j2[#pi%cPJH8?6j
  # print out the help and exit51Testing软件测试网!b7Q Y)E4H1C6h%X#kS)K?
  sub usage51Testing软件测试网rD:j}G9g8?
  {51Testing软件测试网-y JM#{"\H{Y
   my $exit = shift @_ || 0; # don't exit unless explicitly told so51Testing软件测试网\m:[+I~\ f:@
   print <'CuA7Z\ag({y0  first.pl [-l] [-h] [-f FILENAME]
Xac YPV0z&T0  
/o2hy#r_0  The -l switch lists the files in the current directory, using /bin/ls -l.51Testing软件测试网$X9z/uu"O/X.n-l
  The -f switch selects a different configuration file. The -h51Testing软件测试网3pg;N0U3l-K d#^
  switch prints this help. Without the -l or -h arguments, will show
C["s/} ~A0  a command prompt.51Testing软件测试网{_d%J-N7nUL
  
,uf*C;Q%eS8M0  Commands you can use at the prompt:
r1? u)N'h$`0  51Testing软件测试网7^(S%}w+\8N
   list:          list the files in the current directory
\.x BWp(v0   listlong:        list the files in the current directory in long format51Testing软件测试网 zE.T6I#C*u X$Kv
   help:          print out this help51Testing软件测试网7s!qF h4o8J7e
   quit:          quit the program51Testing软件测试网CKt,zr sr \9D
  
-k S5X)qF0  EOHIPPUS
*iEa1bE:s;kt0   exit if $exit;51Testing软件测试网-mH;Tn@})tw"Z
  }  51Testing软件测试网Zr;OYX5R
  51Testing软件测试网(}zu4i8h$|({|5\R
  这里,通常会有三种选择:51Testing软件测试网 fv.zW#P
  51Testing软件测试网df-PT$Ug}a R+u
  由于可能会有多个开关组合,所以程序的 UI 会复杂到不可忍受的程度。51Testing软件测试网 EPE,O:z/Y_
  UI 将发展为 GUI。51Testing软件测试网&yaR5}ucdq
  从头重新开发 UI,使其至少带有一些解析功能。
6tp LB9V;?3lXr#G+l0  51Testing软件测试网C`Q5s(tg.W{V
  第一种选择太可怕,难以去想象。这里不讨论第二种选择,但它的确在向后兼容性和灵活性方面提出了有趣的挑战。第三种选择是本文下面要讨论的内容。
_D_zcA\*W'm4R0  
j+\W1pJx0  Parse::RecDescent 的快速教程
wqk(g zP0  Parse::RecDescent 是一个用于解析文本的模块。通过几个简单构造就可以用它完成几乎所有的解析任务。更高级的文法构造可能会让人望而生畏,不过在大多数用途中不需要这么高级的文法。
d-Fm'PRD0  
bh,S'{*B#j/bMQ0  Parse::RecDescent 是一个面向对象的模块。它围绕着文法创建解析器对象。文法(grammar)是一组以文本形式表示的规则。下面这个示例是一条匹配单词的规则:
*e4du8z/cBL0  51Testing软件测试网 @{)dE5QE
  word 规则
@Pon o0  word: /\w+/   
e2CgBbH*k0  
3O9Ix5q"`&It0  这条规则一次或多次匹配字符(\w)。跟在冒号后的部分称为产品(production)。一条规则必须包含至少一个产品。一个产品可以包含其它规则或直接要匹配的内容。下面这个示例是一条规则,它可以匹配一个单词、另一条规则(non-word)或一个错误(如果其它两个都失败):
$k/z*Pi M7nIC0  
sc wg4KG0  另一些产品
&~4wr,w2n-M0  token: word | non-word |
3Y%Wa!SW|n0  word: /\w+/51Testing软件测试网$nlsd k
  non-word: /\W+/   51Testing软件测试网xT%I?}%@1s_1o6{
  
H+y0Xe:Z^(x vH4o3IB0  每个产品也可以包含一个用花括号括起的操作:
O'O2aa1Z\N,A0  
2\8}!Jjhh b H)d R0  产品中的操作
BG-}EUz0  print: /print/i { print_function(); }   
gr K*U |0R|4Zm0  51Testing软件测试网V0l l-NLntv;D
  如果操作是产品中的最后一项,则操作的返回码决定产品是否成功。该操作是一种空产品,它将总是会匹配,除非它返回 0。
%u3\"FK*N0  51Testing软件测试网T rJ(} O4?5|O
  可以用 (s) 修饰符指定多个标记(token):
2p+?)W J0M2E6L+L0  51Testing软件测试网S P3UtN
  一个产品中带一个或多个标记
bl;V vx Sy-mt.h0  word: letter(s)
m9P4d)O,c+N.bWf0  letter: /\w/   51Testing软件测试网@o^^ HB [*K
  51Testing软件测试网-oyU*fr"uw
  也可以将 (?)(0 或 1)和 (s?)(0 到 N)修饰符作为可选关键字来使用。51Testing软件测试网V K MB ~%n W0_ NRU"B
  
k4y6G6Z2R[$`8qg7Q0  可以通过 $item[position] 或 $item{name} 机制来访问产品中的任何内容。请注意,在第二种情形中,两个单词的名称是相同的,所以必须使用位置查找。在第三种情形中,单词数组以数组引用的形式存储在 $item{word} 中。如果在产品中使用可选项,则数组定位方案将肯定无法很好地工作。一般来说,无论如何都应避免使用这种方案,因为通过名称查找的方式总是更方便更简单:
dw,T_J0  51Testing软件测试网 Ky#l3I,d yP8W
  使用 %item 和 @item 变量51Testing软件测试网 q5w:\w5P$L
  print: /print/i word { print_function($item{word}); }51Testing软件测试网)~-XH(~*J0Z7@;wT:O
  print2: /print2/i word word { print_function($item[1], $item[2]); }51Testing软件测试网.|{!y"ClZ2@
  print3: /print3/i w

TAG: perl

 

评分:0

我来说两句

Open Toolbar