Be Brave

my 2c da bastian contrario, rispetto a quello che dice Maurizio De
Santis :slight_smile:

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

Ottima l’idea di limitare le eccezioni ignorate gist :slight_smile:
Ho aggiornato il post con questa implementazione.

2015-08-07 9:38 GMT+02:00 gabriele renzi [email protected]:

+1

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

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