Ruby 什么';这段代码中逗号的作用是什么?
我试图用方法来理解这段代码。每个带有对象的。 我不明白逗号(在Ruby 什么';这段代码中逗号的作用是什么?,ruby,Ruby,我试图用方法来理解这段代码。每个带有对象的。 我不明白逗号(在units[name]之后)在块内是如何工作的 更清楚地说,它的功能是什么? 为什么有一个逗号将单位[name]与秒数=…分开,而不是写为单位[name,seconds=seconds…” 这是一段代码: units=durations。每个带有_对象({})的|(名称,持续时间),单位| 单位[名称],秒=秒。divmod(持续时间) end.reject{| k,v | v.zero?}.map(&singularize) 在Ru
units[name]
之后)在块内是如何工作的
更清楚地说,它的功能是什么?
为什么有一个逗号将单位[name]
与秒数=…
分开,而不是写为单位[name,seconds=seconds…”
这是一段代码:
units=durations。每个带有_对象({})的|(名称,持续时间),单位|
单位[名称],秒=秒。divmod(持续时间)
end.reject{| k,v | v.zero?}.map(&singularize)
在Ruby中,您可以通过以下方式“解构”数组并将其绑定到多个变量a,b=[1,2]
,其中1
将绑定到a
和2
到b
。举个例子:
[1] pry(main)> a, b = [1, 2]
=> [1, 2]
[2] pry(main)> a
=> 1
[3] pry(main)> b
=> 2
知道这一点,上述代码与
units=durations。每个带有_对象({})的|(名称,持续时间),单位|
结果=秒。divmod(持续时间)
单位[名称]=结果。第一个
秒=result.last
结果
end.reject{| k,v | v.zero?}.map(&singularize)
思考您的问题时,单位[name,seconds=seconds….]
无效。散列的[]
方法只需要一个参数。您可以定义自己的类来接受更多
# The following was tested on ruby 2.6
class A
def [](name, surname)
puts "#{name} #{surname}"
end
def []=(name, surname, value)
puts "#{name} #{surname} = #{value}"
end
end
a = A.new
a['foo', 'bar'] # prints 'foo bar'
a['foo', 'bar'] = 'baz' # prints 'foo bar = bar'
因此,您可以定义自己的哈希实现来实现您所描述的功能,但默认情况下它不会。似乎.map(&singularize)
与这个问题并不相关,所以我将其删除
样本数据
让我们分析一下这个代码片段。为此,我们需要一些数据。我猜,持续时间
可能看起来像下面这样,但实际结构可能并不重要
seconds = 1630
durations = [["Bob", 3600], ["Melba", 60]]
鲍勃以小时为单位消耗时间;梅尔巴,几分钟后
枚举数
我们首先定义一个枚举数
enum = durations.each_with_object({})
#=> #<Enumerator: {"Bob"=>3600, "Melba"=>60}:each_with_object({})>
数组分解
分解enum.next的过程被调用。这个链接值得仔细阅读。事实上,整个文件编写得很好,内容丰富。请注意|(名称、持续时间)、单位|
中的括号如何与数组持续时间
中的括号相对应。另见
块计算
现在可以执行块计算
units[name], seconds = seconds.divmod(duration)
#=> units["Bob"], seconds = 1630.divmod(3600)
#=> units["Bob"], seconds = [0, 1600]
units
#=> {"Bob"=>0}
seconds
#=> 1630
我们再次使用了数组分解。由于duration
等于Bob(3600)的每小时秒数,units[“Bob”]
设置为等于他“消耗”的小时数,seconds
现在等于剩余秒数。由于后者保持不变(1630
),我们推断Bob只能以小时的倍数消耗时间,因此他消耗了零秒
{"Bob"=>0, "Melba"=>27}.reject { |k, v| v.zero? }
#=> {"Melba"=>27}
枚举生成的第二个值
在块通知enum它已准备好生成另一个元素之后,我们有以下步骤
(name, duration), units = enum.next
#=> [["Melba", 60], {"Bob"=>1}]
name
#=> "Melba"
duration
#=> 60
units
#=> {"Bob"=>0}
请注意,单位
已更新。继续
units[name], seconds = seconds.divmod(duration)
#=> units["Melba"], seconds = 1630.divmod(60)
#=> units["Melba"], seconds = [27, 10]
units
#=> {"Bob"=>0, "Melba"=>27}
seconds
#=> 10
我们看到梅尔巴消耗了27
分钟的1630
秒,剩下10
秒
块从enum
请求下一个元素
块现在可以从enum
获取另一个元素
(name, duration), units = enum.next
#=> #StopIteration (iteration reached an end)
enum
引发了一个stopInteraction
异常,因为它没有更多的元素可提供。这导致块返回单位的值({“Bob”=>0,“Melba”=>27}
)
删除非时间消费者
最后,我们摆脱了所有消耗零秒的人
{"Bob"=>0, "Melba"=>27}.reject { |k, v| v.zero? }
#=> {"Melba"=>27}
更复杂的数组分解示例
这里有两个
arr = [[1, {a:2}, [3, [4, 5..6]]], 7]
(a, b, (c, (d, e))), f = arr
a #=> 1
b #=> {:a=>2}
c #=> 3
d #=> 4
e #=> 5..6
f #=> 7
[arr].each do |(a,b,(c,(d,e))),f|
puts a
puts b
puts c
puts d
puts e
puts f
end
1
{:a=>2}
3
4
5..6
7
再次将括号的位置与arr
中括号的位置进行比较
数组分解的使用非常有用,但似乎没有得到充分利用。非常感谢您的评论,它对理解Ruby中的语法非常有帮助。谢谢Shello Cary非常感谢您的时间和非常完整的解释。我已经保存了你建议的一些链接。谢谢