2012-01-14 2 views
2

В рубине я не совсем уверен, как обращаться с нулевыми объектами.Ruby - правильная обработка нулевых объектов

Например, я следующее:

begin 
    sp = SerialPort.new(@serial_device, @serial_bps, @serial_par, @serial_bits, SerialPort::NONE) 
    tcp = TCPSocket.new(@host, @port) 

    if (sp) 
     sp.print(command) 
     sp.close 
    elsif 
     tcp.print(command) 
     tcp.close 
    end 

    say siri_output 
rescue 
    pp $! 
    puts "Sorry, I encountered an error: #{$!}" 
ensure 
    request_completed 
end 

Проблема заключается в том, что первый объект возвращает ошибку, связанную с:

No route to host - connect(2)

Что является правильным, потому что TCP не подключен duh. Поэтому я бы хотел, чтобы вместо этого использовался следующий объект.

Есть ли способ сделать это, не используя определенные Исключения, мне было интересно, есть ли лучший способ сделать то, что я за каким-то образом.

+0

Не могли бы вы использовать функцию, чтобы проверить доступность того, что делает соединения? –

+1

obj.nil? - рубиновый способ проверки объекта для nil – Fivell

ответ

3

Проблема не в проверках, вы делаете это правильно. Все, что не ноль или ложь, истинно в рубине. Дело в том, что когда вы получаете исключение в строке, начинающейся с «sp = ..», выполнение переходит к блоку resque. Вы должны реструктурировать код, как это (я удалил условие обеспечения, потому что я не знаю, что он делает). Хорошо сделать это, чтобы спасти каждый конкретный тип исключения в собственной строке. по имени класса ex. NoConnectivityException => e (или какой будет класс исключения).

begin 
    sp = SerialPort.new(@serial_device, @serial_bps, @serial_par, @serial_bits, SerialPort::NONE) 
    sp.print(command) 
    sp.close 
    say siri_output 
rescue Exception => e 
    puts "Sorry, I encountered an error: #{e.inspect}" 
    puts "trying TCP" 
    begin 
     tcp = TCPSocket.new(@host, @port) 
     tcp.print(command) 
     tcp.close 
     say siri_output 
    rescue Exception => e 
     puts "Sorry, I encountered an error: #{e.inspect}" 
    end 
end 

Для быстрого и неаккуратного программирования вы можете сделать еще одну вещь, но это не рекомендуется и, как правило боль для отладки, так как любые результаты ошибок в ноле и глушителем.

sp = SerialPort.new(@serial_device, @serial_bps, @serial_par, @serial_bits, SerialPort::NONE) rescue nil 
tcp = TCPSocket.new(@host, @port) rescue nil 

Таким образом, вы бы в конечном итоге ни с объектом SerialPort или нулевой объект в переменной зр, и то же самое для зр.

+1

'обеспечить' - это структура, подобная' finally' в Java или C#. – Hauleth

+0

Да, я знаю. Я просто не понимаю, что предложение делает здесь осмысленно, если у вас есть спасение всех исключений, то вы можете просто получить его за пределами всего начала/спасения. Это необходимо только в том случае, если вы воссоздаете исключение или некоторые исключения могут проскользнуть. Кроме того, что делает «request_completed»? Как связанный сетевой файл с "siri_output". – sunkencity

+0

А также это не сухим способом. – Hauleth

Смежные вопросы