2013-08-17 32 views
5

Tôi đang cố gắng mã hóa một máy khách hai luồng bằng ruby, một luồng đọc dữ liệu từ một ổ cắm và in ra, luồng kia đọc dữ liệu cục bộ và gửi nó đến máy chủ từ xa. Vấn đề tôi thấy là nó trông giống như Ruby không thể nắm bắt được các lỗi trong một chủ đề, đây là một ví dụ:Làm thế nào để làm cho Ruby nắm bắt lỗi cú pháp trong các chủ đề

#! /usr/bin/ruby 

Thread.new { 
    loop { 
    $stdout.puts "hi" 
    abc.puts ef 
    sleep 1 
    } 
} 


loop { 
    sleep 1 
} 

Rõ ràng, ngoài các chủ đề nếu tôi gõ abc.puts ef mã sẽ không bao giờ chạy từ Ruby sẽ báo cáo "biến không xác định abc ". Tuy nhiên, nếu nó nằm trong một chuỗi, không có báo cáo lỗi. Câu hỏi của tôi là, làm thế nào để Ruby bắt lỗi như thế này? Hoặc ít nhất, báo cáo một cái gì đó là sai trong một sợi?

+0

'SyntaxError' không được nâng lên, nhưng' NameError'. – falsetru

Trả lời

6

Sử dụng Thread::abort_on_exception=:

Theo Thread - Exception Handling:

Bất kỳ chủ đề có thể nâng cao một ngoại lệ sử dụng phương pháp nâng cao, hoạt động tương tự như Kế hoạch rnel # nâng cao.

Tuy nhiên, điều quan trọng cần lưu ý là ngoại lệ xảy ra trong bất kỳ chủ đề nào ngoại trừ chủ đề chính phụ thuộc vào abort_on_exception. Tùy chọn này là false theo mặc định, có nghĩa là bất kỳ ngoại lệ không được xử lý nào sẽ làm cho chuỗi kết thúc âm thầm khi chờ bằng cách tham gia hoặc giá trị. Bạn có thể thay đổi mặc định này bằng cách hủy abort_on_exception = đúng hoặc đặt $ DEBUG thành true.

...

Thread::abort_on_exception = true 
Thread.new { 
    loop { 
    $stdout.puts "hi" 
    abc.puts ef 
    sleep 1 
    } 
} 


loop { 
    sleep 1 
} 

=>

hi 
t.rb:5:in `block (2 levels) in <main>': undefined local variable or method `abc' for main:Object (NameError) 
     from t.rb:3:in `loop' 
     from t.rb:3:in `block in <main>' 
0

Ok, một giải pháp khả thi là bao quanh lambda chủ đề với beginrescueend khối:

Thread.new { 
begin 
    abc.puts ef 
rescue 
    puts error 
end 
} 
Các vấn đề liên quan