2013-08-02 21 views
7

Đó là an toàn hơn & tốt hơn & sạch hơn & được khuyến nghị sử dụng?Sử dụng Try :: Tiny hoặc Eval?

tôi đã sử dụng:

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"); 
} 

Nhưng đối với loại trường hợp (xem phần lỗi), tôi đã được cho biết rằng việc sử dụng Thử :: Tiny là tốt hơn?

Câu hỏi của tôi là: Bạn sẽ viết như thế nào và tại sao bạn lại chọn cách đó?

Trả lời

10

Cập nhật

Nhờ một người dùng vô danh tôi đã có thể để sửa một lỗi trong câu trả lời của tôi. Các return trong khối catch không có hiệu quả mong muốn, vì nó chỉ trả về từ chương trình con catch.

Nếu không có ngoại lệ, try trả về giá trị của khối try, nếu không giá trị của khối catch. Vì vậy, phiên bản này thực hiện đúng và trả về giá trị $c->redirect("/index") nếu số insert thành công, nếu không nó sẽ gọi và trả về giá trị $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 là khá nhiều điều cần thiết như xử lý với eval lỗi là rất khó khăn thực sự để có được quyền trong trường hợp tổng quát. Tài liệu của mô-đun cho biết điều này

Mô-đun này cung cấp các câu lệnh cố định/thu thập/cố định xương trần để giảm thiểu các lỗi thường gặp với eval blocks và NOTHING else.

Trọng tâm chính của mô-đun này là cung cấp xử lý lỗi đơn giản và đáng tin cậy cho những người ... vẫn muốn viết các khối eval chính xác mà không cần 5 dòng lò hơi mỗi lần.

Mã của bạn sẽ trông như thế này

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"); 
} 

mà tôi hy vọng bạn sẽ đồng ý là đẹp hơn nhiều.

Hai điểm đáng chú ý:

  • trycatchthủ tục con mã hoá để trông giống như từ ngôn ngữ. Điều đó có nghĩa là dấu chấm phẩy sau cú đúp cuối cùng là điều cần thiết.

  • Vì lý do tương tự, return trong các khối try hoặc catch sẽ không hoạt động như mong đợi và sẽ chỉ cần thoát khỏi khối, quay lại chương trình con mẹ. Xem cập nhật của tôi ở trên.

  • Trong khối catch[email protected] có giá trị ban đầu từ trước try. Giá trị phát sinh từ lỗi là ở $_

+0

thực sự đẹp hơn nhiều – ado

+0

An * người dùng ẩn danh * không đủ danh tiếng để đăng nhận xét đã cố gắng chỉnh sửa câu trả lời của tôi, thêm văn bản này. Đó là một điểm rất tốt và tôi đã thực hiện một bản cập nhật thích hợp. * Với 'Try :: Tiny' việc xây dựng đẹp hơn nhưng khác biệt đáng kể so với bài gốc. Khi bạn đã viết try và catch blocks là các chương trình con, do đó sự trở lại bên trong catch chỉ trả về từ sub ẩn danh, không phải từ 'insert_exec'. Nó có nghĩa là chuyển hướng cũng được thực hiện trong trường hợp ngoại lệ. Đây là một cạm bẫy phổ biến của 'Try :: Tiny'. * – Borodin

4

Không sử dụng Try::Tiny giúp bạn tiết kiệm thêm sự phụ thuộc.

Sử dụng nó cho phép bạn viết mã dễ hiểu mà không cần biết kiến ​​thức về thành ngữ Perl (bằng cách thay thế chúng bằng cụm từ thường được công nhận trên toàn ngành).

Bạn cần quyết định xem giá trị nào trong số đó có giá trị hơn đối với bạn, vì thật khó đo lường giá trị tương đối của chúng một cách khách quan.

1

Tốt nhất là không phải dựa vào [email protected] để báo hiệu lỗi, nhưng chỉ sử dụng nó như là nguồn gốc của thông báo lỗi, vì vậy tôi sẽ viết nó như:

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

Nếu bạn đang eval'ing một cái gì đó mà có thể không trả về một giá trị thực sự thành công, sau đó:

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

tôi có lẽ sẽ sử dụng Hãy thử :: Tiny khi mọi thứ trở nên phức tạp hơn hơn thế này, ví dụ: hàm trả về giá trị bạn muốn lưu, nhưng có thể không phải là giá trị thực (hoặc thậm chí không thể xác định được) và bạn muốn bắt ngoại lệ.

Các vấn đề liên quan