2012-01-19 68 views
22

我在Perl 5.8上,需要指定一個默認值。最後我做這個:使用三元運算符分配?

if ($model->test) { 
    $review = "1" 
} else { 
    $review = '' 
} 

$model->test值將是要麼"1"或不確定。如果$model->test中有某些內容,請將$review設置爲"1",否則將其設置爲''

因爲它不是Perl 5.10我不能使用新的時髦定義或操作符。我的第一反應是使用三元運算符是這樣的...

defined($model->test) ? $review = "1" : $review = ''; 

但也不能工作。

有沒有人有一個想法如何更有效地分配這個? 珍妮

+0

你真的應該將它設置爲'1'不是'「」 '。它們都具有相同的字符串表示('''')。唯一的區別是''''會警告你是否試圖將它作爲一個數字使用,而'!1'將會改變。 (假設你總是有'使用警告;'在每一個Perl代碼的頂部,就像你應該。) –

回答

32

我通常寫爲:

$review = (defined($model->test) ? 1 : ''); 

在括號裏的清晰度爲其他人閱讀的代碼。

+0

謝謝格雷格!我甚至覺得很奇怪,因爲它看起來很簡單。 (它是!)JW –

+0

@JaneWilkie其實,它比這更容易,甚至。看到我的答案。 – tchrist

+0

當然,WAY更好的答案是將MySQL的定義更改爲CHAR(1)而不是BIT(1),但不幸的是,在我們的生產環境中改變這種簡單事情的政策是巨大的。 –

9

$model->test將會是"1"或未定義。如果有什麼東西在$model->test,設置$review"1"否則設置''

然後,只需使用:

$review = $model->test || ""; 
+0

湯姆和福伊在同一個線程中。拉里沃爾在哪裏?我希望我們所有人排隊,這樣我就可以和你們一起拍我的照片。 – Alhadis

2

首先,「這並沒有工作,要麼」是不是最有用的東西你可以告訴我們。重要的是要確切知道如何它不起作用:它做了什麼,你期望什麼,以及它們如何不同?

但隨着

defined($model->test) ? $review="1" : $review=''; 

問題是運算符優先級。有條件的經營者? :結合比賦值運算符=更緊密,因此上述等同於:

(defined($model->test) ? $review="1" : $review) = ''; 

所以,如果$model->test定義,它的

$review = "1" = ''; 

可以解決這個問題相當於括號:

defined($model->test) ? ($review="1") : ($review=''); 

但是真的,你爲什麼要?當你想使用結果時,條件(三元)運算符很有用。如果結果將被丟棄,因爲它是在這裏,它更清晰(和,正如你所看到的,不易出錯),以使用if/else語句:

if (defined($model->test) { 
    $review = "1"; 
} 
else { 
    $review = ""; 
} 

,或者,如果你堅持在寫它在同一行:

if (defined($model->test) { $review = "1"; } else { $review = ""; } 

如果你真的想用一個條件表達式,你可以這樣做:

$review = defined($model->test) ? "1" : ""; 

這可能是一個合理的方式做到這一點。

BUT:

defined操作者本身產生任一"1"(真)或""(假)。所以整個事情可以減少到:

$review = defined($model->test); 
+0

如果'undef'只是一個錯誤值,並且該方法被重寫爲返回''''或'0'爲假值? –

+0

@BradGilbert:那麼我想你不想將'defined'應用於它。您顯然需要知道該方法返回以便能夠使用它。 –

+0

測試()的工作不是提供適用於其他用途的值,並且依賴於這種方式會是一種糟糕的形式。這種東西導致了緊密的耦合和嚴格的測試。 –

20

您有一個優先問題。你有什麼是一樣的

(defined($model->test) ? $review="1" : $review) = ''; 

你可以使它與parens工作。

my $review; $model->test ? ($review='1') : ($review=''); 

但是,將作業移出工作要乾淨得多。

my $review = $model->test ? '1' : ''; 

當然,你可以簡單地使用

my $review = $model->test || ''; 

但是爲什麼改變民主基金爲空字符串?

my $review = $model->test; 
1
my $result = defined $model->test ? '1' : ''; 
+0

將'$ result'設置爲與$ result = defined $ model-> test;'幾乎相同的值。主要區別在於,如果用作數字,則會發出警告。 –

2

我認爲$model->test應該返回一個true或false值。

除非明確指出假值爲undef,否則該方法可以被重寫爲開始返回一些其他的假值。 這會破壞任何只檢查值是否被定義的東西。
(我認爲這是該方法返回undef而不是規範的錯誤值的錯誤。)

所以設置$review是測試返回值的真實性的最好方式;不是它的定義。

my $review = $model->test ? 1 : ''; 

我想指出的是,這仍然存在一個錯誤。 如果您希望能夠將該值作爲數字使用,則它會在出現錯誤時發出警告。

要解決此問題,您應該返回!1(規範的假值),該值將返回字符串''的值,但也具有數值0。

my $review = $model->test ? 1 : !1; 

注意,它可以只是簡單:

my $review = !! $model->test; # invert it twice 

如果你只是想改變值,只有當它是假的,你可以使用或操作||

my $review = $model->test || !1; 

如果你真的只是想知道,如果它被定義,或者不是你爲什麼不只是使用defined

my $review = defined $model->test; 

如果你想改變的價值只有當它是不確定的,你有Perl 5.10或更高版本,你可以使用defined-or operator (//)

my $review = $model->test // !1; 

對於一個較老的Perl,這需要一個以上的statement

my $review = $model->test; 
$review = !1 unless defined $review; 
7

除了條件運算符,我經常喜歡用do,從最後計算的表達式返回值:

my $review = do { 
    if(...) { 'foo' } 
    elsif(...) { 'bar' } 
    elsif(...) { 'baz' } 
    else   { 'defaut' } 
    }; 
+0

在這種情況下,這有點矯枉過正。但是,向你的工具箱添加另一種技術總是值得的,謝謝。 –