Warning come eccezione (Era: rescue warning)

2010/1/4 Paolo M. [email protected]:

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 :slight_smile:

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 :slight_smile:

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…

2010/1/6 Alessandro S. [email protected]:

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 :slight_smile:

2010/1/7 Alessandro S. [email protected]:

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 :slight_smile:

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 :slight_smile:

gabriele renzi wrote:

2010/1/6 Alessandro S. [email protected]:

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 :slight_smile:

Perchè…? basta che modifichi la classe Exception… mica devi
modificare il tuo codice…

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 :slight_smile:

Siamo in 2 :slight_smile:

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…)