加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

perl: Use of uninitialized value

发布时间:2020-12-15 20:59:38 所属栏目:大数据 来源:网络整理
导读:原文网址:http://perl5maven.com/use-of-uninitialized-value This is one of the most common warning you will encounter while running Perl code. It is a warning,it won't stop your script from running and it is only generated ifwarnings were t

原文网址:http://perl5maven.com/use-of-uninitialized-value

This is one of the most common warning you will encounter while running Perl code.

It is a warning,it won't stop your script from running and it is only generated ifwarnings were turned on. Which is recommended.

The most common way to turn on warnings is by including a use warnings; statementat the beginning of your script or module.

The older way is adding a -w flag on the sh-bang line. Usually looks like thisas the fist line of your script:

#!/usr/bin/perl -w

There are certain differences,but as use warnings is available for 12 years now,there is no reason to avoid it. In other words:

Always use warnings;!------总是使用use warnings是 比较通用的方式,因为这种做法已经产生12年了

Let's go back to the actual warning I wanted to explain.

A quick explanation

 
 
  1. Use of uninitialized value $x in say at perl_warning_1.pl line 6.

This means the variable $x has no value (its value is the special valueundef).Either it never got a value,or at some pointundef was assigned to it.

You should look for the places where the variable got the last assignment,or you should try to understand why that piece of code has never been executed.

A simple example

The following example will generate such warning.

 
 
  1. use warnings;
  2. use strict;
  3. use 5.010;
  4. ?
  5. my $x;
  6. say $x;

Perl is very nice,tells us which file generated the warning and on which line.

Only a warning

As I mentioned this is only a warning. If the script has more statements after thatsay statement,they will be executed:

 
 
  1. use warnings;
  2. use strict;
  3. use 5.010;
  4. ?
  5. my $x;
  6. say $x;
  7. $x = 42;
  8. say $x;

This will print

 
 
  1. Use of uninitialized value $x in say at perl_warning_1.pl line 6.
  2. 42

Confusing output order

Beware though,if your code has print statements before the linegenerating the warning,like in this example:

 
 
  1. use warnings;
  2. use strict;
  3. use 5.010;
  4. ?
  5. print 'OK';
  6. my $x;
  7. say $x;
  8. $x = 42;
  9. say $x;

the result might be confusing.

 
 
  1. Use of uninitialized value $x in say at perl_warning_1.pl line 7.
  2. OK
  3. 42

Here,the result of the first say is seen after the warning,even though it was called before the code that generated the warning.

This strangeness is the result of IO buffering.By default Perl buffers STDOUT,the standard output channel,while it does not buffer STDERR,the standard error channel.

So while the word 'OK' is waiting for the buffer to be flushed,the warning message already arrives to the screen.

以下为上面三句英文的翻译(意译,非直译):

第7行的say $x的警告先出现,而不是出现在pirnt 'OK'的结果后面,可能让人有些搞不清楚。

在背后捣鬼的就是IO 缓冲。默认情况下,Perl的STDOUT是有缓冲的(即使将STDOUT输出至某句柄也是有缓冲的,因为来一个字符就输出的话,会使硬盘的磁头不停的旋转寻找位置,慢效率又低,存够一块的字符然后在输出,磁头旋转的次数很少,效率就提高了)(只有缓冲区buffer满了或者程序要结束时才会输出结果),而STDERR是没有缓冲的,所以STDERR有输出的话,会直接将结果显示出来(如果没有将STDERR输出导向句柄的话,默认输出至显示器)。-----参考书籍《Learning Perl》Chapter5 Input and Output

结合本例的话,就是warnings因为没有缓冲,直接输出至显示器;print的OK和42,因为字符太少缓冲区没满,只能程序结束时才输出了。所以才会出现这样子的结果。

如果想关闭STDOUT的缓冲的话,将变量$|设置为1即可。因为将变量$|设置为1,每一次输出操作,都会使选择的句柄刷新缓冲。(有点费解,上英文原句:Setting the special $| variableto 1 will set the selected filehandle (the one selected at the time the variable is modified)? to flush the buffer after each output operation.)见下例:turining off buffering

Turning off buffering

In order to avoid this you can turn off the buffering of STDOUT.

This is done by the following code: $| = 1;at the beginning of the script.

 
 
  1. use warnings;
  2. use strict;
  3. use 5.010;
  4. ?
  5. $| = 1;
  6. ?
  7. print 'OK';
  8. my $x;
  9. say $x;
  10. $x = 42;
  11. say $x;

 
 
  1. OKUse of uninitialized value $x in say at perl_warning_1.pl line 7.
  2. 42

(The warning is on the same line as the OK because we have not printed a newlinen after the OK.)

The unwanted scope

 
 
  1. use warnings;
  2. use strict;
  3. use 5.010;
  4. ?
  5. my $x;
  6. my $y = 1;
  7. ?
  8. if ($y) {
  9. my $x = 42;
  10. }
  11. say $x;

This code too produces Use of uninitialized value $x in say at perl_warning_1.pl line 11.

I have managed to make this mistake several times. Not paying attention I usedmy $xinside theif block,which meant I have created another $x variable,assigned 42 to it just to let it go out of the scope at the end of the block.(The $y = 1 is just a placeholder for some real code and some real condition.It is there only to make this example a bit more realistic.)

There are of course cases when I need to declare a variable inside an if block,but not always.When I do that by mistake it is painful to find the bug.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读