Chinaunix首页 | 论坛 | 博客
  • 博客访问: 59656
  • 博文数量: 13
  • 博客积分: 25
  • 博客等级: 民兵
  • 技术积分: 65
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-07 08:01
文章分类

全部博文(13)

文章存档

2014年(1)

2013年(2)

2012年(11)

我的朋友

分类: Python/Ruby

2013-10-19 01:43:59

函数的使我们可以用一个统一的接口来处理不同个数或类型的数据输入。很多语言支持这一概念,多是通过多态性原型的定义来实现的。而Perl可以让我们通过hash参数来实现函数的多态性,从而使函数在调用上更为灵活,且很大程度上降低了开发成本。这一能力是其他语言所不具备的。这是如何实现的呢?

我们知道,perl的hash可以视为一个大小为偶数的array。且在这一前提下的array可以与hash相互赋值。


  1. %hash = @array;
  2. @array = %hash;
我们可以通过这一特性使函数的参数结构为hash,使函数可以通过hash来调用参数。

下面举个小例子。一个函数greet(),它可以用多种语言打招呼。注意 my %param = @_; 即是array赋值予hash的操作。

点击(此处)折叠或打开

  1. sub greet
  2. {
  3.     my %param = @_;
  4.     my $name = $param{name} ||= '';
  5.     my $lang = $param{lang} ||= 'en';

  6.     my %hi =
  7.     (
  8.         en => 'hi',
  9.         fr => 'bonjour',
  10.         ge => 'hallo',
  11.         it => 'ciao',
  12.         sp => 'hola',
  13.     );

  14.     if ( defined $hi{$lang} )
  15.     {
  16.         printf "%s %s\n", $hi{$lang}, $name;
  17.     }
  18.     else
  19.     {
  20.         print "don't know how to greet in this language\n";
  21.     }
  22. }
这样在调用greet()函数时我们可以在其参数的个数、默认值及输入顺序上随心所欲。对于没有定义的参数,函数会忽略不计,正常运行。

点击(此处)折叠或打开

  1. greet(); # hi
  2. greet( name => 'tom' ); # hi tom
  3. greet( lang => 'ge' );  # hallo
  4. greet( name => 'dick', lang => 'it' );  # ciao dick
  5. greet( lang => 'fr', name => 'harry' ); # bonjour harry
  6. greet( junk => "doesn't matter" ); # hi
而具有hash参数的函数的优势不仅局限于此。假设我们为greet()增加了一个功能,调用时通过参数'greet'选择选择问候或道别。

点击(此处)折叠或打开

  1. sub greet
  2. {
  3.     my %param = @_;
  4.     my $name = $param{name} ||= '';
  5.     my $lang = $param{lang} ||= 'en';
  6.     my $greet = $param{greet} ||= 'hi';

  7.     my %hi =
  8.     (
  9.         en => 'hi',
  10.         fr => 'bonjour',
  11.         ge => 'hallo',
  12.         it => 'ciao',
  13.         sp => 'hola',
  14.     );

  15.     my %bye =
  16.     (
  17.         en => 'bye',
  18.         fr => 'au revoir',
  19.         ge => 'auf wiedersehen',
  20.         it => 'arrivederci',
  21.         sp => 'adios',
  22.     );

  23.     $greet = $greet eq 'hi' ? \%hi : \%bye;

  24.     if ( defined $greet->{$lang} )
  25.     {
  26.         printf "%s %s\n", $greet->{$lang}, $name;
  27.     }
  28.     else
  29.     {
  30.         print "don't know how to greet in this language\n";
  31.     }
  32. }
由于参数'greet'的默认值是‘hi',过去的调用方式完全不受影响。即增加了下述新功能的同时,上面调用greet()函数的代码也不需要改写。也就是说此函数在调用上具备自然的向后兼容性!

点击(此处)折叠或打开

  1. greet(); # hi
  2. greet( name => 'tom' ); # hi tom
  3. greet( lang => 'ge' );  # hallo
  4. greet( name => 'dick', lang => 'it' );  # ciao dick
  5. greet( lang => 'fr', name => 'harry' ); # bonjour harry
  6. greet( junk => "doesn't matter" ); # hi

  7. greet( greet => 'bye' ); # bye
  8. greet( name => 'tom', greet => 'hi' ); # hi tom
  9. greet( greet => 'bye', lang => 'ge' ); # auf wiedersehen
  10. greet( name => 'dick', greet => 'bye', lang => 'it' ); # arrivederci dick
  11. greet( lang => 'fr', name => 'harry', greet => 'hi' ); # bonjour harry
阅读(413) | 评论(0) | 转发(0) |
0

上一篇:1.1 起步 - 关于版本控制

下一篇:RewriteRule

给主人留下些什么吧!~~