J'ai déjà fait quelque chose comme ça dans ruby. C'était juste un test pour voir si je pouvais implémenter les "exceptions resumables" du lisp commun dans ruby. Vous devriez être capable de faire la même chose avec Scala, mais je ne l'ai pas essayé. Votre question concerne-t-elle le concept général ou les détails de la mise en œuvre?
Quoi qu'il en soit, voici le code (sans garantie;))
#!/usr/bin/env ruby
require 'continuation'
#Module for adding elements of an array. Leaves error handling to the caller by using exceptions and continuations.
module Adder
#Exception class that offers continuations to the receiver.
class CcExc < Exception
def initialize(again, skip, index, sum)
@again = again
@skip = skip
@index = index
@sum = sum
end
def again
@again.call
end
def skip
@skip.call
end
attr_reader :index #where the problem occured
attr_reader :sum #current sum
end
#Method to get the current continuation
def Adder.getcc
cc = nil
callcc {|c| cc = c}
cc
end
#add all numbers in the array, raise an exception with continuations if an
#item doesn't have the right type
def Adder.addAll(array)
sum = 0;
array.each_with_index {|dummy,i|
again = getcC#save continuation before processing the item
if array[i].is_a? Numeric
sum += array[i] #process item normally
else
#raise exception with previously save continuation (again)
#and current continuation (skip)
callcc {|skip| raise CcExc.new again, skip, i, sum}
end
}
sum
end
end
data = [1,"2",3,"hello",Object,"4",5,"END",6]
begin
puts "The sum is #{Adder.addAll data}."
rescue Adder::CcExc => e
puts "Exception raised."
i = e.index
case data[i]
when /^\s*\d/
data[i] = data[i].to_i
puts 'Problem fixed. Continue adding.'
e.again
when "END"
puts "'END' found. Stop processing."
puts "The sum is #{e.sum}"
else
puts "'#{data[i]}' of type #{data[i].class} can't be converted " +
"to interger. Item skipped."
e.skip
end
end