I am new to ruby and lots of things are confusing me. I believe this specific one is from Sorbet which is some type checking library? not sure. This specific piece of code is right before a method declaration
sig { params(order: T::Hash[
String, T.any(
T.nilable(String), T::Hash[
String, T.any(
Integer, T.nilable(String)
)
]
)
]).returns(Types::Order) }
def self.build_prescription(prescription)
# method implementation
The order
object is a json object coming from REST API. Can someone explain what this nesting thing is going on.
This is indeed a Sorbet signature. You can read more about Sorbet in their official documentation
The signature itself in this case is just describing the shape of the parameters and return type of the build_prescription
method.
Slightly reformatting to make it easier to annotate:
sig { # A ruby method added by Sorbet to indicate that the signature is starting.
params( # Start to declare the parameters that the method takes
order: T::Hash[ # First param. In this case, it's a Hash...
String, # ... where they key is a String ...
T.any( # ... and the value can be either: ...
T.nilable(String), ... # a nilable String
T::Hash[ # or a Hash ...
String, # ... where the key is a String...
T.any(Integer, T.nilable(String)) # ... and the value is either an Integer or nilable string String
]
)
])
.returns(Types::Order) # Declaration of what the method returns
}
def self.build_prescription(prescription) # the regular Ruby method declaration
Note, though, that this will fail a Sorbet validation, as the signature declares the parameter as order
, while the method declares it as prescription
. Those two names should match.
There's a way to re-write this signature to make it a bit nicer to read/understand
sig do
params(
prescription: T::Hash[
String,
T.nilable(
T.any(
String,
T::Hash[String, T.nilable(T.any(Integer, String)]
)
)
])
.returns(Types::Order) # Declaration of what the method returns
}
def self.build_prescription(prescription)
Note that I'm moving the T.nilable
s out one level, as T.any(Integer, T.nilable(String))
means that same as T.nilable(T.any(Integer, String))
but it's more immediately obvious for a reader that the value can be nil