I have an HDF5 file I'd like to read 2 arrays from. How can I get them using the do
block notation?
using HDF5
function myfunc()
h5open("path", "r") do f
a = read(f, "a")
b = read(f, "b")
end
# ... do some more processing of a, b
return a, b
end
If I run that, it will error after the do block with a not defined
. How do I get the values so I can process them after, without wrapping the full computation in the do
block?
A do
block is just syntax for creating an anonymous function that is passed as the first argument (to h5open
in this case`). Just like regular functions, you need to return any values from the anonymous function that you want to use on the "outside":
# Function to mimic Base.open, HDF5.h5open etc
function open(f)
return f()
end
function g()
a, b = open() do
c = "hello"
d = "world"
return c, d # returns from the "do"-anonymous function
end
return a, b
end
You can define local
variables in the outer function like this:
julia> function f()
local a, b
map(10) do x
a = x + 1
b = x + 2
end
return a, b
end
f (generic function with 1 method)
julia> f()
(11, 12)
The downside of this approach is that compiler will not be able to make it type stable in all cases and also might be boxing a
and b
(both things happen in my example). What @fredrikekre proposes is a preferred approach AFAICT. See:
julia> @code_warntype f()
Variables
#self#::Core.Compiler.Const(f, false)
b@_2::Core.Box
a@_3::Core.Box
#1::var"#1#2"
a@_5::Union{}
b@_6::Union{}
Body::Tuple{Any,Any}
1 ─ (b@_2 = Core.Box())
│ (a@_3 = Core.Box())
│ (#1 = %new(Main.:(var"#1#2"), b@_2, a@_3))
│ %4 = #1::var"#1#2"
│ Main.map(%4, 10)
│ %6 = Core.isdefined(a@_3, :contents)::Bool
└── goto #3 if not %6
2 ─ goto #4
3 ─ Core.NewvarNode(:(a@_5))
└── a@_5
4 ┄ %11 = Core.getfield(a@_3, :contents)::Any
│ %12 = Core.isdefined(b@_2, :contents)::Bool
└── goto #6 if not %12
5 ─ goto #7
6 ─ Core.NewvarNode(:(b@_6))
└── b@_6
7 ┄ %17 = Core.getfield(b@_2, :contents)::Any
│ %18 = Core.tuple(%11, %17)::Tuple{Any,Any}
└── return %18
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With