2013-08-02 62 views
7

哪種更安全&更好&清潔劑&更多推薦使用?使用Try :: Tiny或Eval?

我用:

sub insert_exec { 
    my ($self, $c, $args) = @_; 
    my ($params, $table, $model) = $self->_init({context => $c, args => $args}); 
    eval { $model->insert($table, $params); 
    }; 
    if ([email protected]) { return $c->show_error([email protected]); } ## error 
    $c->redirect("/index"); 
} 

但對於這類案件(見的錯誤的部分),我已被告知,使用try :: Tiny是更好?

我的問題是:你會如何寫這個,你爲什麼選擇這種方式?

回答

10

更新

感謝匿名用戶我已經能夠糾正的錯誤在我的答案。 catch塊中的return沒有達到預期的效果,因爲它僅從catch子例程返回。

如果沒有異常,則try返回try塊的值,否則返回catch塊的值。因此,如果insert成功,則此版本正確執行並返回$c->redirect("/index")的值,否則它將調用並返回值$c->show_error($_)

sub insert_exec { 
    my ($self, $c, $args) = @_; 
    my ($params, $table, $model) = $self->_init({context => $c, args => $args}); 
    try { 
    $model->insert($table, $params); 
    $c->redirect("/index"); 
    } 
    catch { 
    $c->show_error($_); 
    }; 
} 

Try::Tiny是非常必要的,因爲誤差eval處理是很艱難的,以得到正確的一般情況。該模塊的文檔說這個

該模塊提供了裸體骨架try/catch/finally語句,旨在最大限度地減少與eval塊的常見錯誤,沒有別的。

該模塊的主要重點是爲那些仍然希望每次沒有5行樣板編寫正確評估塊的人員提供簡單可靠的錯誤處理。

您的代碼應該是這樣的

use Try::Tiny; 

sub insert_exec { 
    my ($self, $c, $args) = @_; 
    my ($params, $table, $model) = $self->_init({context => $c, args => $args}); 
    try { 
    $model->insert($table, $params); 
    } 
    catch { 
    return $c->show_error($_); 
    }; 
    $c->redirect("/index"); 
} 

,我希望你會同意是更好。

有兩點值得注意:

  • trycatch子程序編碼看起來像語言的話。這意味着最後一個右大括號後面的分號是必不可少的。如預期

  • 出於同樣的原因,returntrycatch塊內將無法正常工作,並會簡單地退出塊,返回到父子程序。看到我上面的更新。

  • catch區塊[email protected]的原始值爲try之前。從錯誤中得到的值是$_

+0

確實好多了 – ado

+0

匿名用戶沒有足夠的聲望發表評論,試圖編輯我的答案,添加此文本。這是一個很好的觀點,我做了一個適當的更新。 *通過'Try :: Tiny',建設更好,但與原來的帖子大不相同。正如你所寫的,try和catch塊是子例程,因此catch內部的返回僅從匿名sub中返回,而不是從'insert_exec'中返回。這意味着在發生異常的情況下也執行重定向。這是'Try :: Tiny'的常見錯誤。* – Borodin

4

不使用Try::Tiny爲您節省了額外的依賴性。

使用它可以讓您編寫在不知道Perl成語的情況下可以理解的代碼(通過將其替換爲業界普遍認可的術語)。

您需要決定哪些對您更有價值,因爲很難客觀衡量其相對價值。

1

最好不要依賴[email protected]信號錯誤,但只是把它作爲錯誤消息的來源,所以我把它寫成:

my $success = eval { $model->insert($table, $params) }; 
unless ($success) { 
    return $c->show_error([email protected]); 
} 

如果您eval'ing東西,可能不會成功返回真值,則:

my $success = eval { $model->insert($table, $params); 1 }; 

我可能會嘗試使用微型::當事情變得更加複雜比如,函數返回一個你想要保存的值,但可能不是一個真正的值(或者甚至可能沒有定義),並且你想要捕獲異常。