This can be easily achieved with a helper higher order function:

def with_graph(opts // [], fun) do
  g = :digraph.new(opts)
  try do
    fun.(g)
  after
    :digraph.delete(g)
  end
end

And, later in the code you can call:

with_digraph(fn graph ->
  # some operations
end)

This guarantees proper cleanup, and doesn’t require any additions to the 
language. It also allows you to separate all the lifetime code from the 
algorithm. It’s a pretty common pattern for guaranteed cleanup when you have 
higher order functions.

Michał.

> On 05 Aug 2016, at 19:39, Filip Haglund <[email protected]> wrote:
> 
> I often find myself writing
> 
> def func(a,b):
>   g = :digraph.new
> 
>   ...
> 
>   out = some_long_multiline_expression_using_g
>   :digraph.delete g
>   out
> end
> 
> when working with graphs. The distance between `:digraph.new` and 
> `:digraph.delete` makes it harder to remember to clean up the graph ets 
> tables. The little dance at the end to return a value and also clean up the 
> mutable state feels a bit awkward too. This problem is common when working 
> with mutex, files and other things you need to remember to clean up. Golang 
> has a great solution; the `defer` statement.
> 
> def func(a,b):
>   g = :digraph.new
>   defer :digraph.delete g
> 
>   ...
> 
>   some_long_multiline_expression_using_g
> end
> 
> This minimizes the distance between declaration and cleanup statement, makes 
> it harder to forget it, and also cleans up the end of the function. If there 
> isn't a `defer` just after some mutable state is created, you immediately 
> know that you need to figure out where the mutable state is cleaned up. If 
> there is a `defer` statement there, you can read the rest of the code without 
> having to think about if every branch has the proper clean-up code in it.
> 
> Each `defer` statement pushes a function call onto a stack, with the variable 
> bindings it had when the `defer` statement was reached. When the function 
> returns, the function calls on the stack are executed one by one.
> 
> 
> --
> You received this message because you are subscribed to the Google Groups 
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/elixir-lang-core/2c0d8195-ec44-4112-a0c1-2f5c5f3905b2%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/3E344A7F-046A-43A9-A849-200AE25BEC8B%40muskala.eu.
For more options, visit https://groups.google.com/d/optout.

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

Reply via email to