Best way to ensure only certain values are allowed for a particular arg?

xiaodai
Sat, 05 Oct 2024 07:06:21 +0000
General Usage

In trying to write a clone of numpy API in Julia, I see the numpy.array has an argument which accepts only 4 values but is other a string in Python.

The 4 possibles values are C , F, A, K. So I want to make sure that arg only accepts these 4 values. So the first thing I tried is to make a struct with a construction

struct ARRAY_ORDER
    order::Char

    ARRAY_ORDER(order) = begin
        @assert order in ('C', 'F', 'A', 'K')
        new(order)
    end
end

then I thought, actually because the order value is typed Char technically someone can make a constructor and do type piracy and allow some other value to be input. So that’s not ideal.

Another way is to put an assert into the array function in Julia but I prefer to use types of restrict.

AI says to use Enum which is also problematic as it requires conversation and I want to store the order as Char as originally intended.

Then I focused on this solution which I think is safe from type-piracy.

struct ARRAY_ORDER
    order::Union{Val{'C'}, Val{'F'}, Val{'A'}, Val{'K'}}

    ARRAY_ORDER(order::Char) = begin
        new(Val(order))
    end

    ARRAY_ORDER(order::String) = begin
        @assert length(order) == 1 "order must be a single character"
        orderchar = String[1]
        new(Val(orderchar))
    end
end

which is using Val and setting order to be a few distinct values using the Val constructor to turn values into types.

Is this the best way? Are there alternatives?

5 posts - 4 participants