2016-10-16 56 views
4

我在我的腳本下面幾行:字符串重載變量被視爲定義不管什麼

my $spec = shift; 
if (!defined $spec) { 
    return ("Invalid specification", undef); 
} 
$spec = "$spec" // ''; 

我自然會想到這,通過undef時,數組中返回警告Invalid specification,與第二項目是undef。相反,檢查通過了,我收到控制檯消息,警告我在下一行有Use of uninitialized value $spec in string

$spec是一個帶有字符串和數字重載的對象,不幸的是這樣寫的,試圖在這個特定的子例程中測試真實性(例如通過if ($spec))導致深遞歸和段錯誤。

雖然我興趣,爲什麼,到底,發生這種情況,我感興趣的是如何讓它停止發生。我想消除控制檯警告,最好不要使用no warnings qw/uninitialized/。這是可能的,如果是這樣,我該怎麼做?

+0

嘗試'$規範// = '''或'$規範定義= $規範呢? 「$ spec」:''' –

+0

偉大的問題。 – Zaid

回答

7

你說$spec是一個對象string overloading

如果是這樣的話,那麼你需要檢查它被定義之前,它強制轉換成String形式:每YSTH

if (! defined overload::StrVal($spec)) { 

修正

由於YSTH在StrVal指出,不強制重載字符串化:

過載:: StrVal(ARG)

給出arg的字符串值,因爲沒有stringify重載。如果你使用這個來獲取引用的地址(對於檢查兩個引用是否指向相同的東西很有用),那麼使用Scalar :: Util :: refaddr()會更好。

因此,要做到這一點,試試他的其他建議:

「$規範」陷阱警告和檢測未初始化的VAR警告。最好在類中添加一個方法來測試任何返回undef的情況。

下面演示了這種方法:

#!/usr/bin/env perl 

use strict; 
use warnings; 

use Test::More tests => 2; 

my $obj_str_defined = StringOverloaded->new("has value"); 
my $obj_str_undef = StringOverloaded->new(undef); 

ok(is_overloaded_string_defined($obj_str_defined), qq{\$obj_str_defined is defined}); 
ok(!is_overloaded_string_defined($obj_str_undef), qq{\$obj_str_undef is undef}); 

sub is_overloaded_string_defined { 
    my $obj = shift; 

    my $is_str_defined = 1; 

    local $SIG{__WARN__} = sub { 
     $is_str_defined = 0 if $_[0] =~ /Use of uninitialized value \$obj in string/; 
    }; 

    my $throwaway_var = "$obj"; 

    return $is_str_defined; 
} 

{ 
    # Object with string overloading 
    package StringOverloaded; 

    use strict; 
    use warnings; 

    use overload (
     '""' => sub { 
      my $self = shift; 
      return $$self; # Dereference 
     }, 
     fallback => 1 
    ); 

    sub new { 
     my $pkg = shift; 
     my $val = shift; 
     my $self = bless \$val, $pkg; 

     return $self; 
    } 
} 

輸出:

1..2 
ok 1 - $obj_str_defined is defined 
ok 2 - $obj_str_undef is undef 
+2

我不認爲這就是想要的:'overload :: StrVal(arg) 給出arg的字符串值,因爲沒有stringify重載。 '。也就是說,它將以字符串形式返回對象引用,例如Foo = HASH(0xdeadbeef) – ysth

+0

@ysth我認爲你是對的。你知道強制字符串形式而不使用串聯的正確方法嗎? – Miller

+1

「$ spec」捕獲警告並檢測未初始化的var警告。最好在類中添加一個方法來測試任何返回undef的情況。 – ysth