For this question, The things what i want to do is like following Ruby code:
options = {foo: true}
options[:bar] = "String" if true
options
def some_method(**options)
p options
end
some_method(**options)
current, my solution is: (probably do things a wrong way, please point it out)
options = {foo: true}
options = options.merge(bar: "String") if true
p options # => {foo: true, bar: "String"}
p typeof(options) # => (NamedTuple(foo: Bool) | NamedTuple(foo: Bool, bar: String))
def some_method(**options)
p options
end
some_method(**options)
# Error: double splatting a union (NamedTuple(foo: Bool) | NamedTuple(foo: Bool, bar: String)) is not yet supported
So, how to fix it? or, is there a more practical way to achieve this?
You have got the understanding of Tuple, NamedTuple wrong. They are fixed-size, immutable, and stack-allocated objects, whose type need to be known at compile time.
What you are accomplishing is a runtime behavior, so you should be leaning toward approach that works for your cited use-case.
if you insist to use double splatting, then you can create NamedTuple from Hash (something like below) though I don’t see any reasoning for following such approach:
options = {:foo => true} of Symbol => Bool | String
options[:bar] = "String" if true
p options # => {:foo => true, :bar => "String"}
p typeof(options) # => (Hash(Symbol, Bool | String)
def some_method(**options)
p options # => {foo: true, bar: "String"}
end
some_method(**{foo: Bool, bar: String}.from(options))