処理の中断
Rubyの勉強
処理に時間がかかるループなどを中断させたい場合は
catch(:str){ throw :str, var }
を使用するのが便利。throwを実行した時点でcatch{……}から抜ける。
loopとbreakの組合せでも同じようなこと可能だが、こちらは多重のループからもぬけることができる。throwに2番目に引数varが設定されている場合はcatchはその値を返す。
下の例ではボタン1あるいはボタン2を押すことで2重の無限ループから抜ける。メソッドstop1,stop2を並行処理させるため、無限ループはTreadのブロックとしている。
#!/usr/bin/env ruby require "qte" require "qpe" require "thread" include Qte include Qpe class SampleWindow < QMainWindow def initialize() super() setCaption(tr("サンプル")) @msg = QLabel.new(tr("これはサンプルプログラム"),self) @msg.setGeometry(10,10,300,30) @ebox1 = QMultiLineEdit.new(self) @ebox1.setGeometry(0,100,635,300) @ebox1.setReadOnly(true) @pb1 = QPushButton.new(tr("Start"),self) @pb1.setGeometry(300,5,100,30) connect(@pb1,QSIGNAL("clicked()"), self, 'cnt') @pb2 = QPushButton.new(tr("Stop1"),self) @pb2.setGeometry(405,5,100,30) connect(@pb2,QSIGNAL("clicked()"), self, 'stop1') @pb3 = QPushButton.new(tr("Stop2"),self) @pb3.setGeometry(510,5,100,30) connect(@pb3,QSIGNAL("clicked()"), self, 'stop2') @pbStop1 = false @pbStop2 = false end def cnt Thread.new { #stop1,stop2を並行処理させるためスレッド作成 Thread.pass @ebox1.clear @pbStop1 = false @pbStop2 = false i = catch(:exit) { @ebox1.insertLine("loop1 start") while true #無限ループ1 @ebox1.insertLine("loop2 start") while true #無限ループ2 if @pbStop1 then #ボタン1が押されたら抜ける throw :exit, "Pb1" end if @pbStop2 then #ボタン2が押されたら抜ける throw :exit, "Pb2" end end end } #throwでcatchのブロックを抜ける @ebox1.insertLine("stop by #{i}") #iはthrowの2番目の引数 } end def stop1 @pbStop1 = true end def stop2 @pbStop2 = true end end $defaultCodec = QTextCodec.codecForName("utf8") app = QPEApplication.new([$0]+ARGV) app.setDefaultCodec($defaultCodec) QApplication.setFont(QFont.new("lcfont",18)) app.showMainWidget(SampleWindow.new) app.exec