You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, splat destructuring in multiple assignment works if and only if a type implements #[](Int). This has unintended consequences:
a, b, c ="12345"# okay?
a, b, c = {0 => 'x', 1 => 'y', 2 => 'z'} # okay??
a, b, c, d, e =Pointer(UInt8).malloc(1) # ?????
There should be a #to_array_splat method that is called on the RHS expression whenever 1-to-n multiple assignment occurs, and also whenever a splat expression is expanded inside a container literal in #3718. (This is analogous to #to_ary in Ruby, although Ruby uses #to_a instead for the latter case.) Then we could reject code like above by simply not defining the method in Hash and String and so on, while at the same time supporting splat expansion of custom data types:
record Point, x : Int32, y : Int32dodefto_array_splat
{@x, @y}
endend
x, y =Point.new(x:1, y:2)
# the above is equivalent to:
__temp =Point.new(x:1, y:2).to_array_splat
x = __temp[0]
y = __temp[1]
Standard library that could define #to_array_splat are Indexable, Regex::MatchData, and Class (to support expansion of Tuple metaclasses).
This doesn't change the semantics of other splat expansions where an exact Tuple type is expected; the naming makes it clear that the splat only works for array-like contexts (otherwise it might have been to_tuple_splat or to_single_splat). For example:
deffoo(x, y)
end
foo(*Point.new(x:1, y:2)) # not alloweddefbaryield*Point.new(x:1, y:2) # not allowedend
Likewise, there could be a #to_hash_splat customization point for hash-like double splats, which the language currently doesn't support yet, but might due to #3718 (comment). (Similar to the array case, calling a method with ** requires an exact NamedTuple type so doesn't count.)
The text was updated successfully, but these errors were encountered:
This issue is extracted from #3718 (comment).
Currently, splat destructuring in multiple assignment works if and only if a type implements
#[](Int)
. This has unintended consequences:There should be a
#to_array_splat
method that is called on the RHS expression whenever 1-to-n multiple assignment occurs, and also whenever a splat expression is expanded inside a container literal in #3718. (This is analogous to#to_ary
in Ruby, although Ruby uses#to_a
instead for the latter case.) Then we could reject code like above by simply not defining the method inHash
andString
and so on, while at the same time supporting splat expansion of custom data types:Standard library that could define
#to_array_splat
areIndexable
,Regex::MatchData
, andClass
(to support expansion ofTuple
metaclasses).This doesn't change the semantics of other splat expansions where an exact
Tuple
type is expected; the naming makes it clear that the splat only works for array-like contexts (otherwise it might have beento_tuple_splat
orto_single_splat
). For example:Likewise, there could be a
#to_hash_splat
customization point for hash-like double splats, which the language currently doesn't support yet, but might due to #3718 (comment). (Similar to the array case, calling a method with**
requires an exactNamedTuple
type so doesn't count.)The text was updated successfully, but these errors were encountered: