my 2c da bastian contrario, rispetto a quello che dice Maurizio De
Santis
L’esempio specifico secondo me non “eccezioni come control flow”, in
quanto non
necessariamente sei tu che stai facendo raise dell’eccezione per avere
un
control flow non lineare.
Ovvero: eccezioni come control flow
def fetch(url)
body, status = _fetch(url)
raise HttpError if status == 4xx
raise EmptyBody if body.empty?
raise InvalidJson unless body.valid_json?
end
mentre
data = fetch(url) rescue {}
solo “gestisci libreria”.
Ma concordo invece con il problema che l’esempio per come scritto
pericoloso perch non c’ controllo su cosa dovrebbe gestire.
Per, ad esempio avendo a che fare con librerie che usano eccezioni in
modo
abbastanza liberale (praticamente tutte quelle che hanno a che fare con
http), io ho spesso usato roba tipo
def ignoring(exception_classes)
begin
yield
rescue *exception_classes => e
log_exception "error ", e
# e per esempio in rails, qua metti anche un @error = ...
end
end
…
ignoring(RequestTimeOut, ConnectionError) {
data = fetch_data()
do_stuff_with(data)
}
Che altro non che “if”, con un altro nome.
YMMV
Ottima l’idea di limitare le eccezioni ignorate gist
Ho aggiornato il post con questa implementazione.
2015-08-07 9:38 GMT+02:00 gabriele renzi [email protected]:
Ok, ma fallisce nei casi ibridi in cui la navigazione passa accesso
tramite
hash e metodi, come nell’esempio originale:
params[:profile][:resume].tempfile.path
Al posto di creare un Optional ancora più complesso posso semplicemente
usare l’implementazione di base con un wrap iniziale su una OpenStruct:
require 'ostruct'
require 'monads/optional'
include Monads
Optional.new(OpenStruct.new(params)).profile.resume.tempfile.path.value
Monadic Bravery
2015-08-07 10:39 GMT+02:00 maurizio de magnis
[email protected]:
Se non fosse che Monads
sembra fare a botte con OpenStruct
:
[25] pry(main)> Monads::Optional.new(OpenStruct.new({foo: 'bar',
spam:
{egg: ‘rick’}})).spam.egg.value
NoMethodError: undefined method egg' for {:egg=>"rick"}:Hash from /Users/olistik/.rvm/gems/ruby-2.2.2/gems/monads-0.0.1/lib/monads/monad.rb:11:in
public_send’
mentre con Hashie::Mash
sembra andare d’amore e d’accordo:
[26] pry(main)> Monads::Optional.new(Hashie::Mash.new({foo: 'bar',
spam: {egg: ‘rick’}})).spam.egg.value
=> “rick”
2015-08-07 10:41 GMT+02:00 Elia S. [email protected]: