Forum: Italian Ruby user group Warning come eccezione (Era: rescue warning)

Posted by gabriele renzi (Guest)
on 2010-01-06 00:03
(Received via mailing list)
2010/1/4 Paolo Montrasio <paolo@paolomontrasio.com>:
> la stessa cosa, creando una classe Warning che derivi da Exception e che
> faccia la puts del messaggio nell'initialize, ma è possibile che ci
> siano dettagli dei warning smalltalk che mi sfuggono.

Mh.. non son sicuro ma credo sia più complesso. La cosa che stampa non
è l'eccezione, ma l'handler, per cui sarebbe

def foo()
  warn
 rescue Warning
   puts warning.message
end

Ma considera il codice

def read_logs(io)
  io.each do |line|
    do_parse(line)
  end
end

def do_parse(line)
  if ....
    ...
  else
  warn("parsing went wrong")
   nil
  end
end

se la warn lanciasse un'eccezione invece di fare side effect il flusso
di controllo in ruby  sarebbe interrotto, e fondamentalmente
irrecuperabile. In  Smalltalk esiste la possibilità di fare un #resume
dell'eccezione per cui l'handler può limitarsi a fare la print su
stderr dell'errore e poi riprendere il flusso normale.

Avevamo un po' di smalltalker in lista, chissà che fine han fatto :)
Posted by Alessandro Scolavino (ninjinka)
on 2010-01-06 10:16
> 
> def do_parse(line)
>   if ....
>     ...
>   else
>   warn("parsing went wrong")
>    nil
>   end
> end
> 
> se la warn lanciasse un'eccezione invece di fare side effect il flusso
> di controllo in ruby  sarebbe interrotto, e fondamentalmente
> irrecuperabile. In  Smalltalk esiste la possibilit� di fare un #resume
> dell'eccezione per cui l'handler pu� limitarsi a fare la print su
> stderr dell'errore e poi riprendere il flusso normale.
> 
> Avevamo un po' di smalltalker in lista, chiss� che fine han fatto :)

e se lo fai così :

def do_parse(line)
  begin ...
     ...
  rescue Exception => e
      puts "Warning .... #{e.inspect}"
      return e
  end
end

chiaramente puoi anche chiamare un metodo, o modificare la classe 
Exception per ar sì che a seconda dell'errore faccia output e continui 
oppure faccia output ed esca oppure esca solo o non faccia niente...

Posted by gabriele renzi (Guest)
on 2010-01-07 22:59
(Received via mailing list)
2010/1/6 Alessandro Scolavino <scolas@gmail.com>:

>
> chiaramente puoi anche chiamare un metodo, o modificare la classe
> Exception per ar sì che a seconda dell'errore faccia output e continui
> oppure faccia output ed esca oppure esca solo o non faccia niente...

devi moltiplicare il codice che gestisce le eccezioni e stampa in
tutto il tuo codice, se hai eccezioni resumabili basta che ci sia un
exception handler per l'intero programma, è abbastanza diverso :)
Posted by Alessandro Scolavino (ninjinka)
on 2010-01-07 23:07
gabriele renzi wrote:
> 2010/1/6 Alessandro Scolavino <scolas@gmail.com>:
> 
>>
>> chiaramente puoi anche chiamare un metodo, o modificare la classe
>> Exception per ar s� che a seconda dell'errore faccia output e continui
>> oppure faccia output ed esca oppure esca solo o non faccia niente...
> 
> devi moltiplicare il codice che gestisce le eccezioni e stampa in
> tutto il tuo codice, se hai eccezioni resumabili basta che ci sia un
> exception handler per l'intero programma, � abbastanza diverso :)

Perchè..? basta che modifichi la classe Exception... mica devi 
modificare il tuo codice...
Posted by gabriele renzi (Guest)
on 2010-01-08 10:01
(Received via mailing list)
2010/1/7 Alessandro Scolavino <scolas@gmail.com>:

>> devi moltiplicare il codice che gestisce le eccezioni e stampa in
>> tutto il tuo codice, se hai eccezioni resumabili basta che ci sia un
>> exception handler per l'intero programma, � abbastanza diverso :)
>
> Perchè..? basta che modifichi la classe Exception... mica devi
> modificare il tuo codice...

nel tuo esempio hai aggiunto un begin/end, che è modificare il tuo
codice. Se modifichi exception per fargli stampare output non cambia
il fatto che interrompe il flusso di controllo, perché è #raise che lo
cambia non Exception::new. Inoltre, se fai la puts in
Exception#initialize hai perso la possibilità di avere controllo su di
essa

Scusa, non riesco a spiegarmi bene o non capisco quel che dici.

Questo funzionerebbe in un ruby con eccezioni resumabili:

# la roba commentata sarebbe nel main interpreter loop, nascosta 
all'utente
# begin

def warn(msg)
 raise(Warning.new(msg))
end

def read_logs(io)
 io.each do |line|
   do_parse(line)
 end
end

def do_parse(line)
 if ....
   ...
 else
 warn("parsing went wrong")
 end
end

# here we silence warnings in a thread safe granular way
def ignoring_warns()
  do_parse "broken line"
 rescue Warning w #
  if w.message == "parsing went wrong" #skip
   w.resume
  end
end

# rescue Warning w
#  if Log.level < w.level
#    $stderr.puts w.message
#  end
#  w.resume
# end

ma #resume non esiste nelle eccezioni ruby (_si può_ emularlo usando
callcc e contorcendosi, ma è molto lento).

Io non vedo un modo in cui cui il codice sopra possa funzionare, e che
quindi non richieda di modificare il codice per accomodare un concetto
di warning-as-exception, ma forse son solo miope :)
Posted by Alessandro Scolavino (ninjinka)
on 2010-01-08 13:11
gabriele renzi wrote:

> 
> def do_parse(line)
>  if ....
>    ...
>  else
>  warn("parsing went wrong")
>  end
> end
> 
> Io non vedo un modo in cui cui il codice sopra possa funzionare, e che
> quindi non richieda di modificare il codice per accomodare un concetto
> di warning-as-exception, ma forse son solo miope :)

Siamo in 2 :)

il tuo problema è che se la exception viene sollevata dentro il ciclo if 
sei comunque a piedi se non modifichi o la classe exception oppure il 
metodo raise (che non è detto debba per forza terminare il programma...)
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.