From: josh.cheek@... Date: 2015-01-06T03:01:12+00:00 Subject: [ruby-core:67358] [ruby-trunk - Feature #10118] Double splat for non-symbol keys Issue #10118 has been updated by Josh Cheek. Yukihiro Matsumoto wrote: > Double splat was introduced to pass a hash given from keyword arguments. > Keyword argument hash is fundamentally a hash with symbol keys. > > Matz. I've always considered the final hash to be a hash of options. I can't think of a reason to split the options hash in two based on whether the keys are symbols. Isn't the purpose that a method can extract whatever options it cares about and then pass the remaining options to the next method? In that case, having them in one hash makes the most sense, otherwise weird things happen, here we see `3..6=>:delete` got turned into its own separate hash and added to the wrong variable. ~~~ def m1(*nums, opts) nums # => [1, 2, 3, 4, 5, {3..6=>:delete}] opts # => {:offset=>2} end # do something with multiplier and pass off to m1 def m2(*nums, multiplier:, **opts) m1(*nums, **opts) end # some options for m2, some for m1 options = { multiplier: 5, offset: 2, 3..6 => :delete } m2(1,2,3,4,5, options) ~~~ To deal with this, you would have to explicitly check the other args for hashes accidentally getting appended to their list. For example, this causes `Open3` to break when the key is the file descriptor (such as `Open3.popen3 'echo message >&3', 3 => $stdout`). As the caller, there is no way for me to pass my arguments such that they are passed correctly to `spawn` since it happens inadvertently between methods down the callstack. Depending on whether my options are symbols or integers, they'll either wind up in `popen_run`'s `opts` or `cmd` argument. So I must edit the source https://github.com/ruby/ruby/pull/808/files or find a different implementation, because I can't know what my users' open3 is going to do. ---------------------------------------- Feature #10118: Double splat for non-symbol keys https://bugs.ruby-lang.org/issues/10118#change-50809 * Author: Tsuyoshi Sawada * Status: Feedback * Priority: Normal * Assignee: Yukihiro Matsumoto * Category: syntax * Target version: current: 2.2.0 ---------------------------------------- The double splat operator ** only seems to work with hashes whose keys are symbols. It will not work when a key is a string, for example. This is true for both ways; for construction: def foo **; end foo(:a => 3) #=> nil foo("a" => 3) #=> ArgumentError: wrong number of arguments (1 for 0) and destruction: def bar *; end bar(**{:a => 3}) #=> nil bar(**{"a" => 3}) #=> TypeError: wrong argument type String (expected Symbol) This is confusing. I propose that the double splat syntax should be extended so that it works even when the keys are not symbols. ---Files-------------------------------- 0001-vm.c-allow-to-splat-non-symbol-keys.patch (2.06 KB) -- https://bugs.ruby-lang.org/