[erlang-questions] Nested Case Statements v.s. multiple functions
Richard A. O'Keefe
ok@REDACTED
Wed Sep 27 07:39:26 CEST 2017
On 26/09/17 6:16 PM, dploop wrote:
> is_integer, is_zero is just a simplified example, and by coincidence,
> they can use in the guard. But in most situations you can't use guard,
> for example in game industry when player want to buy equipment, you
> should check if his coin is sufficient, and then you should check the
> number of equipment is right and then you should check if the equipment
> is valid to exchange and so on. The complex business logic can't be
> easily solved by guard, and Nested Cases is inevitable.
Actually, no. My example shows that something like
try
must_be:at_least(Coin, Price),
must_be:at_least(Equipment, Required),
must_be:exchangeable(Equipment),
New_State = exchange(Equipment, Old_State),
{ok, New_State}
catch
throw:Reason -> {error,Reason}
end
is perfectly possible. Indeed, idiomatic Erlang would be
true = enough_coin(Player, State, Purchase),
true = equipment_amount_right(State, Purchase),
true = is_exchangeable(State, Purchase),
exchange(Equipment, State)
The thing is that error *detection* does have to be done often,
but error *handling* should be rare.
Alternatively, you could have a convention that a function
whose name begins with 'check_' either returns a useful
result, or the trivial result (ok), or throws, and write
check_enough_coin(...),
check_equipment_amount_right(...),
check_is_exchangeable(...),
exchange(...)
Then you can have a general purpose wrapper
catch_check(Fun) ->
try
{ok, Fun()}
catch
throw:Reason -> {error,Reason}
end.
and write
catch_check(fun () ->
check_...
check_...
check_...
exchange(...)
end)
There are many ways to kill this particular cat,
but stuffing it with Nested Cases is not a good one.
More information about the erlang-questions
mailing list