# Change behavior of function based on program state?

**URL:** <https://discourse.julialang.org/t/change-behavior-of-function-based-on-program-state/103452>\
**Category:** General Usage\
**Created:** [September 1, 2023, 6:17pm UTC](https://discourse.julialang.org/t/change-behavior-of-function-based-on-program-state/103452 "2023-09-01T18:17:53Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![frylock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frylock/32/50213_2.png) [@frylock](https://discourse.julialang.org/u/frylock)\
**Post date:** [September 1, 2023, 6:17pm UTC](https://discourse.julialang.org/t/change-behavior-of-function-based-on-program-state/103452/1 "2023-09-01T18:17:53Z")

</div>

I’m reading a binary file that stores a UInt16 that tells me if the rest of the section of the file is little-endian or big-endian. If the result of the read is 0x4d4d, it is little endian, and if it is 0x4949 it is big-endian (there are no other possible values). I had considered handling it like this:

```julia
f_read = read

function swapped_read(s, typ)
    ntoh(read(s, typ))
end

function handle_endianness(io)
    if read(io, UInt16) == 0x4d4d
        global f_read = swapped_read
    end
end

# ... rest of program

```

… but handling this with a global variable feels icky … surely there is a better way?  
Especially since it looks like the global variable has to be untyped …

---

<div class="post-metadata">

**Author:** ![fatteneder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fatteneder/32/33991_2.png) [@fatteneder](https://discourse.julialang.org/u/fatteneder)\
**Post date:** [September 1, 2023, 6:38pm UTC](https://discourse.julialang.org/t/change-behavior-of-function-based-on-program-state/103452/2 "2023-09-01T18:38:43Z")

</div>

Maybe something like this

```julia
function swapped_read(s, typ)
    ntoh(read(s, typ))
end

function handle_endianness(io)
    if read(io, UInt16) == 0x4d4d
        return swapped_read
    else
        return read
    end
end

open(filename, "r") do file
    f_read = handle_endianness(io)
    # proceed with f_read
end

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [September 1, 2023, 6:44pm UTC](https://discourse.julialang.org/t/change-behavior-of-function-based-on-program-state/103452/3 "2023-09-01T18:44:10Z")

</div>

> [@fatteneder](#):
>
> ```julia
> if read(io, UInt16) == 0x4d4d
> return swapped_read
> else
> return read
> end
> 
> ```

This is type-unstable.

Why not just write your own `read` function that takes an endian-ness flag? Something like:

```julia
function myread(io, ::Type{T}, swap::Bool) where {T}
   x = read(io, T)
   return swap ? bswap(x) : x
end

```

Or, if you don’t want to pass a `swap` flag around everywhere, you can stash it in the `io` object by using an [`IOContext`](https://docs.julialang.org/en/v1/base/io-network/#Base.IOContext) wrapper, i.e. replace `io` with `IOContext(io, :byteswap=>swap)` and then call `get(io, :byteswap, false)` anyplace you need to know whether to swap the byte order.

(Even fancier would be to define your own `IO` type that includes a byteswap flag, and then override standard functions like `read` for your `IO` subtype. Then you wouldn’t even have to touch most of your I/O code to explicitly call your `myread` function.)

---

<div class="post-metadata">

**Author:** ![frylock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frylock/32/50213_2.png) [@frylock](https://discourse.julialang.org/u/frylock)\
**Post date:** [September 1, 2023, 6:48pm UTC](https://discourse.julialang.org/t/change-behavior-of-function-based-on-program-state/103452/4 "2023-09-01T18:48:29Z")

</div>

Is there a way to determine the endianness of a system? I know that Python had `sys.byteorder` … ?

Also, the IO subtype that understands swapping sounds very fun.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [September 1, 2023, 6:50pm UTC](https://discourse.julialang.org/t/change-behavior-of-function-based-on-program-state/103452/5 "2023-09-01T18:50:47Z")

</div>

> [@frylock](#):
>
> Is there a way to determine the endianness of a system?

[`ENDIAN_BOM`](https://docs.julialang.org/en/v1/base/io-network/#Base.ENDIAN_BOM)

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [September 1, 2023, 8:51pm UTC](https://discourse.julialang.org/t/change-behavior-of-function-based-on-program-state/103452/6 "2023-09-01T20:51:26Z")

</div>

It’s little. Julia doesn’t run on any computers that are big endian and isn’t likely to in the near future.
