天道酬勤,学无止境

double-splat

Ruby 中的关键字参数解包 (splat)(Keyword arguments unpacking (splat) in Ruby)

问题 下面发生的事情对我来说似乎有点奇怪。 def f(a, b) puts "#{a} :: #{b}" end f(*[1, 2], **{}) # prints "1 :: 2" hash = {} f(*[1, 2], **hash) ArgumentError: wrong number of arguments (3 for 2) f(*[1, 2], **Hash.new) ArgumentError: wrong number of arguments (3 for 2) 这是编译器优化功能吗? 回答1 这是一个 Ruby 的错误,已多次报告(例如我在这里),但尚未修复。 我想自从引入关键字参数功能后,double splat 语法就变得模糊了,这就是这个 bug 的间接原因。 我听说 Matz 正在考虑在未来的 Ruby 版本中引入一种新语法来区分哈希和关键字参数。 回答2 [编辑:我在完成我的回答后看到了@sawa 的回答。 我是对的:这是一个错误!] 当字面的空散列被双重分割并且作为变量值的空散列被双重分割时,会获得不同的结果,在我看来,这是由于 Ruby 中的错误造成的初步证据。 要了解该错误可能存在的原因,请首先考虑将双重散列哈希传递给方法的原因。 假设我们定义了一个带有一些关键字参数的方法: def my_method(x, a: 'cat', b:

2021-12-01 10:38:51    分类:技术分享    ruby   hash   keyword-argument   ruby-2.2   double-splat

Keyword arguments unpacking (splat) in Ruby

What is happening below seems a little strange to me. def f(a, b) puts "#{a} :: #{b}" end f(*[1, 2], **{}) # prints "1 :: 2" hash = {} f(*[1, 2], **hash) ArgumentError: wrong number of arguments (3 for 2) f(*[1, 2], **Hash.new) ArgumentError: wrong number of arguments (3 for 2) Is this a compiler optimization feature?

2021-11-20 06:42:25    分类:问答    ruby   hash   keyword-argument   ruby-2.2   double-splat

两级飞溅TCL(two level splatter TCL)

问题 如果我在 TCL 中有一个过程或命令,并且具有可变数量的参数,则可以使用(如果列表的元素作为输入)“飞溅”运算符,例如: set a [list "ko" ] set m [ list "ok" "bang" ] lappend a {*}$m 但是,如果我想“两次飞溅”怎么办? 即,展平 2 个级别? 按顺序使用它两次,不起作用: set a [list "ko" ] set m [ list [ list "ok" ] [ list "bang" ] ] lappend a {*}{*}$m 额外的字符会出错。 回答1 您已经注意到{*} (故意)没有走两步深。 您的特定示例并不能很好地说明问题,因此我建议这样做: set a [list "ko" ] set m [list [list "a b" "c d"] [list "e f" "g h"]] lappend a {*}$m 在这里,我们得到a ko {{ab} {cd}} {{ef} {gh}} a集合。 这不是你想要的。 但我们可以这样做: lappend a {*}[concat {*}$m] 这给出了: ko {ab} {cd} {ef} {gh} 。 看起来是对的。 但我们真的在做正确的事情吗? 让我们用我们的超级秘密内省器,即representation命令来深入了解: % tcl

2021-11-13 11:57:34    分类:技术分享    arguments   tcl   proc   splat   double-splat

two level splatter TCL

If I have a procedure or a command in TCL, with variable number of arguments, one can use, if a list's elements are as an input, the "splatter" operator, for example: set a [list "ko" ] set m [ list "ok" "bang" ] lappend a {*}$m But, what if I want to "twice splatter"? I.e., flatten 2 levels? Using it twice, in sequence, does not work: set a [list "ko" ] set m [ list [ list "ok" ] [ list "bang" ] ] lappend a {*}{*}$m Will error out on extra character.

2021-11-09 06:36:33    分类:问答    arguments   tcl   proc   splat   double-splat

参数解构(相当于python的double-splat)(Parameter destructuring (equivalent of python's double-splat))

问题 在 python 中,我可以传递一个字典,其键与参数名称匹配的** (double-splat) 运算符: def foo(a, b): print (a - b) args = {'b': 7, 'a': 10} foo(**args) # prints 3 如何在 ES6 中做同样的事情? 这不起作用: function foo(a, b) { console.log(a - b) } args = {b: 7, a: 10} foo(...args) 注意:我正在寻找一种不涉及更改foo签名的解决方案,因为我希望它以任何一种方式使用(有和没有解构)。 所以以下应该工作: foo(<magic>args); foo(123, 456); 奖金问题:为什么错误消息“未定义不是函数”? 这里到底什么是未定义的? (正如@Nina Scholz 在评论中所回答的那样,这是因为...需要其参数具有Symbol.iterator ,它不是为对象定义的)。 回答1 如何在 ES6 中做同样的事情? JS 中没有命名参数,只有位置参数。 所以答案是:你不能。 正如@Andy 建议的那样,您可以做的是通过对象传递模拟命名参数。 function foo({ a, b }) { console.log(a - b); } let args = { b: 7, a: 10 }; foo

2021-10-16 15:27:58    分类:技术分享    javascript   ecmascript-6   destructuring   double-splat

Parameter destructuring (equivalent of python's double-splat)

In python I can pass a dict whose keys match parameters' names with the ** (double-splat) operator: def foo(a, b): print (a - b) args = {'b': 7, 'a': 10} foo(**args) # prints 3 How to do the same in ES6? This doesn't work: function foo(a, b) { console.log(a - b) } args = {b: 7, a: 10} foo(...args) NB: I'm looking for a solution that wouldn't involve changing the signature of foo because I want it to be used either way (with and without destructuring). So the following should work: foo(<magic>args); foo(123, 456); Bonus question: why is the error message "undefined is not a function"? What

2021-05-08 20:52:16    分类:问答    javascript   ecmascript-6   destructuring   double-splat

Double-splat运算符破坏性地修改了哈希-这是一个Ruby错误吗?(Double-splat operator destructively modifies hash – is this a Ruby bug?)

问题 我注意到使用Ruby 2.1.1中的** (双splat)运算符时,我发现这是一个非常令人惊讶的行为。 当在**hash值之前使用键值对时,哈希值保持不变。 但是,如果仅在**hash之后使用键值对,则将永久修改哈希。 h = { b: 2 } { a: 1, **h } # => { a: 1, b: 2 } h # => { b: 2 } { a: 1, **h, c: 3 } # => { a: 1, b: 2, c: 3 } h # => { b: 2 } { **h, c: 3 } # => { b: 2, c: 3 } h # => { b: 2, c: 3 } 为了进行比较,请考虑单*运算符在数组上的行为: a = [2] [1, *a] # => [1, 2] a # => [2] [1, *a, 3] # => [1, 2, 3] a # => [2] [*a, 3] # => [2, 3] a # => [2] 整个数组保持不变。 我们是否认为**有时具有破坏性的行为是故意的,还是看起来更像是个bug? 在这两种情况下,说明**运算符如何工作的文档在哪里? 我也在Ruby论坛中问了这个问题。 更新 该错误已在Ruby 2.1.3+中修复。 回答1 该问题的答案似乎是: 这可能是一个错误,而不是故意的。 核心库rdoc中非常简短地记录了**运算符的行为。

2021-05-06 10:37:52    分类:技术分享    ruby   hash   syntax   splat   double-splat

更改* splat和** splatty-splat运算符对我的对象所做的操作(Change what the *splat and **splatty-splat operators do to my object)

问题 如何覆盖解压缩语法*obj和**obj ? 例如,你能以某种方式创建一个对象thing ,其行为是这样的: >>> [*thing] ['a', 'b', 'c'] >>> [x for x in thing] ['d', 'e', 'f'] >>> {**thing} {'hello world': 'I am a potato!!'} 注意:通过__iter__的迭代(“在事物中使用x”)从* splat解压缩返回不同的元素。 我看了一下operator.mul和operator.pow ,但是这些函数只涉及两个操作数的用法,例如a*b和a**b ,似乎与splat操作无关。 回答1 *迭代对象,并将其元素用作参数。 **迭代对象的keys并使用__getitem__ (等效于括号表示法)来获取键值对。 要自定义* ,只需使您的对象可迭代,并自定义** ,使您的对象成为映射: class MyIterable(object): def __iter__(self): return iter([1, 2, 3]) class MyMapping(collections.Mapping): def __iter__(self): return iter('123') def __getitem__(self, item): return int(item) def __len

2021-04-10 01:19:33    分类:技术分享    python   iterable-unpacking   splat   double-splat

Double-splat operator destructively modifies hash – is this a Ruby bug?

I noticed what I find to be a very surprising behavior with the ** (double-splat) operator in Ruby 2.1.1. When key-value pairs are used before a **hash, the hash remains unmodified; however, when key-value pairs are only used after the **hash, the hash is permanently modified. h = { b: 2 } { a: 1, **h } # => { a: 1, b: 2 } h # => { b: 2 } { a: 1, **h, c: 3 } # => { a: 1, b: 2, c: 3 } h # => { b: 2 } { **h, c: 3 } # => { b: 2, c: 3 } h # => { b: 2, c: 3 } For comparison, consider the behavior of the single-* operator on arrays: a = [2] [1, *a] # => [1, 2] a # => [2] [1, *a, 3] # => [1, 2, 3] a

2021-04-07 07:07:35    分类:问答    ruby   hash   syntax   splat   double-splat

Change what the *splat and **splatty-splat operators do to my object

How do you override the result of unpacking syntax *obj and **obj? For example, can you somehow create an object thing which behaves like this: >>> [*thing] ['a', 'b', 'c'] >>> [x for x in thing] ['d', 'e', 'f'] >>> {**thing} {'hello world': 'I am a potato!!'} Note: the iteration via __iter__ ("for x in thing") returns different elements from the *splat unpack. I had a look inoperator.mul and operator.pow, but those functions only concern usages with two operands, like a*b and a**b, and seem unrelated to splat operations.

2021-03-31 09:24:37    分类:问答    python   iterable-unpacking   splat   double-splat