If I don’t cast type type is Fuse::LowLevel::Request, UInt64, (Fuse::Lib::FuseFileInfo | Int32 | LibC::Stat | Slice(UInt8) | String | UInt64 | Nil), which can’t be passed to the target method because of type restrictions.
If I cast I get the error at the bottom.
Code:
case mdata
# Shouldn't this make mdata available as `{UInt64, String}`?
when {UInt64, String}
case name
when :lookup
lookup_data = mdata.as({UInt64, String})
If you want to match against a tuple type you need to use a tuple in the case , as explained in case - Crystal (section “Tuple Literal”)
I did follow the book. I don’t see a reference to Tuple(types). Is the book wrong?
Comparing against a type will perform an is_a? check
case {value1, value2}
when {String, Int32}
# Matches if value1.is_a?(String) && value2.is_a?(Int32)
# The type of value1 is known to be a String by the compiler,
# and the type of value2 is known to be an Int32
end
Sorry, what I said is wrong. But you need to use Tuple(...) to match against a tuple type. Using {...} matches against a tuple value.
Matching {Int64, String} did match. At runtime it matches.
So the value you have is actually a tuple that has Int64 as a type in the first position, and String in the second one? Then using as won’t work. You would need to do as(Tuple(Int64.class, String.class)).
I think the confusion happens because I can’t see all of your code, just an incomplete snippet so I can’t try anything.
As I said before, if you use when {…} you are not matching against a type but against a value. The compiler only casts when X when X is a type, not a value.
Thank you for the code snippet! With it I can finally understand the problem.
I think this is undocumented, but when you mix two tuple types of the same length, for example Tuple(A, B) | Tuple(C, D), the type is turned into Tuple(A | C, B | D). That means that matching against Tuple(A, B) or matching against Tuple(C, D)will never match.
Instead, I recommend not using tuple types and using record to represent the types that you want.
My advice is to avoid tuples and named tuples as much as possible.
My other solution would make a channel with fibers for each data type. Most apps would need nproc to max_net_connecions Fibers. I don’t know if 8-20 * ncpu fibers with dedicated type channels is faster or a single pool of ncpu fibers inside of a giant case statement.