为什么在子例程中调用print会在字符串中附加1?

时间:2010-10-31 07:09:40

标签: perl printing return-value subroutine

我创建了以下子例程性别来随机打印字符串MALE或FEMALE。调用子例程时,print命令在字符串末尾加上“1”后缀。请参阅下面的示例代码和输出:

sub gender { 
    if ( (int rand(100)) >50) {
        print "MALE  ";
    }
    else {
        print "FEMALE";
    }
}   

foreach (1..5) {
    print &gender, "\n"; 
} 

注意“MALE”或“FEMALE”后缀为“1”

输出:

FEMALE1
FEMALE1
MALE  1
MALE  1
FEMALE1
MALE  1

我正在使用为MSWin32-x86-multi-thread

构建的perl v5.8.9 v5.8.9
  

Binary build 826 [290470] provided by ActiveState http://www.ActiveState.com Built May 24 2009 09:21:05

4 个答案:

答案 0 :(得分:14)

print &gender

调用性别功能并打印它返回的内容。性别本身,作为它在任一分支中做的最后一件事,打印一个字符串。隐式地,它返回其中最后一个表达式的结果(打印“MALE”或打印“FEMALE”),并且当成功时,打印返回1.

所以要么这样做:

sub gender { if ( rand(100) >= 50 ) {print "MALE  ";}  else {print "FEMALE";}}
foreach (1..5) { &gender();  print "\n"; } 

或者这个:

sub gender { if ( rand(100) >= 50 ) {return "MALE  ";}  else {return "FEMALE";}}
foreach (1..5) { print &gender(), "\n"; }

另请注意&gender,&但没有括号,是一种特殊形式的函数调用,通常不是人们的意思;要么放弃&或者在你的电话中添加空括号。

我还纠正了if测试,50%的时间返回男性,50%的时间返回女性,而不是49%和51%。

答案 1 :(得分:8)

让我们的代码变得不恰当:

print gender(), "\n" 
    for 1..5;

sub gender {
    return  int rand(100) > 50 ? 'MALE' : 'FEMALE';
}

那么,我做了什么?

首先:

  1. 不应使用gender调用&子,也不应调用parens。这将调用传递给其调用者的参数的子例程。当你有一堆常见的参数清理代码时,这很方便。但这里不可取或不需要。
  2. 我将sub放在其他代码之后,因为我喜欢将我的代码从高级别读取到特定级别 - 这与C强制您组织事物的方式相反。我不喜欢自下而上阅读我的代码,所以我这样做了。这纯粹是个人偏好。做任何让你开心的事。或者,如果您必须与他人合作,请遵循您已达成一致的标准。
  3. 我将foreach缩短为for。他们做同样的事情,一个人少了。
  4. 我使用for作为语句修饰符。换句话说,我做了一个简单的陈述print $_, "\n";并将for添加到最后。对于简单的任务,它比使用块更好。再次,这是我的意见。有些人将语句修饰符解密为 evil 并且不受欢迎。如果您决定使用它们,请保持简单。 YMMV。
  5. 我摆脱了所提到的额外不需要的打印 ysth
  6. 我没有使用大的if / else块,而是使用了三元运算符(好吧,它实际上只是一个三元运算符,但人们称之为 三元运算符) 。它计算测试值,并根据测试的布尔值,返回两个表达式中的一个结果。如果你想在赋值中使用if / else逻辑,这很方便。

答案 2 :(得分:2)

如果没有明确的return,Perl sub将返回最后一个评估值。 gender返回1,因为在两个执行路径中,它都调用print,返回1。

你应该让gender返回一个字符串,然后是调用者print,或者gender进行打印,并让调用者不对返回值做任何事情

答案 3 :(得分:0)

谢谢大家帮我解决这个问题。我找到了一种制作我想要的图表的方法。 这是我最终做到的;

print   "GENDER    NAME   AGE   HEIGHT  WEIGHT \n";
foreach (1..10) {                       ## Starting foreach loop
$age    = int(rand( 50))+10;
$height = int (rand(40)) + 50;
$weight = int (rand (100)) + 100;
sub randchar4bit {(chr int rand(25)+65).(chr int rand(25)+65). (chr int rand(25)+65).(chr int rand(25)+65)};
sub gender { return (int rand(100)>50)? "MALE    " : "FEMALE  ";} ;

print gender(), "  ", &randchar4bit,   "    $age     $height      $weight   style 1\n";
}; ## closing foreach loop 

它会产生一个很好的输出:

GENDER    NAME   AGE   HEIGHT  WEIGHT
FEMALE    HHRN    41     67      165   style 1
MALE      HNMF    27     63      187   style 1
MALE      NLDB    26     54      165   style 1
FEMALE    REMB    33     71      118   style 1
MALE      TWEW    10     57      122   style 1
MALE      OCSC    35     80      168   style 1
FEMALE    TKTR    25     64      179   style 1
MALE      GMYN    47     73      123   style 1
MALE      YKUG    50     79      148   style 1
FEMALE    HDFW    47     73      159   style 1