Ruby 哈希文字的顺序是否有保证?
Is order of a Ruby hash literal guaranteed?
Ruby,从 v1.9 开始,在遍历哈希时支持确定性顺序;先添加的条目将首先返回。
这是否适用于文字,即 { a: 1, b: 2 }
总是在 b 之前产生 a?
我用 Ruby 2.1 (MRI) 做了一个快速实验,它实际上是一致的,但是语言在多大程度上保证这适用于所有 Ruby 实现?
Hashes enumerate their values in the order that the corresponding keys
were inserted.
有几个位置可以指定 ,即一些被认为是 "The Ruby Language Specification":
的地方
- the ISO Ruby Language Specification
- the RubySpec project
- the YARV testsuite
- The Ruby Programming Language book by matz and David Flanagan
ISO 规范没有说明 Hash
排序:它的编写方式使得所有现有 Ruby 实现都自动符合它,而无需更改,即它被编写为 描述性 当前 Ruby 实现,而不是 规范性 。在编写规范时,这些实现包括 MRI、YARV、Rubinius、JRuby、IronRuby、MagLev、MacRuby、XRuby、Ruby.NET、Cardinal、tinyrb、RubyGoLightly、SmallRuby、BlueRuby 等。特别感兴趣的是 MRI(仅 实现 1.8)和 YARV(仅 实现 1.9(当时)),这意味着规范只能指定 1.8 和 1.9 共有的行为,Hash
排序不是。
RubySpec 项目被其开发人员放弃,因为 ruby-核心开发人员和 YARV 开发人员从未认识到它。但是,它确实(隐含地)specify that Hash
literals are ordered left-to-right:
new_hash(1 => 2, 4 => 8, 2 => 4).keys.should == [1, 4, 2]
这是 Hash#keys
的规范,但是,其他规范测试 Hash#values
与 Hash#keys
、Hash#each_value
和 Hash#each_key
具有相同的顺序与那些相同的顺序,Hash#each_pair
和Hash#each
也具有相同的顺序。
我在 the YARV testsuite 中找不到任何指定保留顺序的内容。事实上,我 根本 找不到任何关于在那个测试套件中订购的东西,恰恰相反:测试会花很长的时间 避免 取决于在订购!
Flanagan/matz 书有点隐式地指定 Hash
章节 9.5.3.6 Hash
迭代器 中的文字顺序。首先,它使用与文档大致相同的公式:
In Ruby 1.9, however, hash elements are iterated in their insertion order, […]
但接下来会继续:
[…], and that is the order shown in the following examples:
在那些例子中,实际上使用了文字:
h = { :a=>1, :b=>2, :c=>3 }
# The each() iterator iterates [key,value] pairs
h.each {|pair| print pair } # Prints "[:a, 1][:b, 2][:c, 3]"
# It also works with two block arguments
h.each do |key, value|
print "#{key}:#{value} " # Prints "a:1 b:2 c:3"
end
# Iterate over keys or values or both
h.each_key {|k| print k } # Prints "abc"
h.each_value {|v| print v } # Prints "123"
h.each_pair {|k,v| print k,v } # Prints "a1b2c3". Like each
在, @mu is too short中提到
h = { a: 1, b: 2 }
is the same as h = { }; h[:a] = 1; h[:b] = 2
并且在 那
nothing else would make any sense
不幸的是,事实并非如此:
module HashASETWithLogging
def []=(key, value)
puts "[]= was called with [#{key.inspect}] = #{value.inspect}"
super
end
end
class Hash
prepend HashASETWithLogging
end
h = { a: 1, b: 2 }
# prints nothing
h = { }; h[:a] = 1; h[:b] = 2
# []= was called with [:a] = 1
# []= was called with [:b] = 2
因此,根据您如何解读书中的那一行以及您如何 "specification-ish" 判断那本书,是的, 保证了文字的顺序。
Ruby,从 v1.9 开始,在遍历哈希时支持确定性顺序;先添加的条目将首先返回。
这是否适用于文字,即 { a: 1, b: 2 }
总是在 b 之前产生 a?
我用 Ruby 2.1 (MRI) 做了一个快速实验,它实际上是一致的,但是语言在多大程度上保证这适用于所有 Ruby 实现?
Hashes enumerate their values in the order that the corresponding keys were inserted.
有几个位置可以指定 ,即一些被认为是 "The Ruby Language Specification":
的地方- the ISO Ruby Language Specification
- the RubySpec project
- the YARV testsuite
- The Ruby Programming Language book by matz and David Flanagan
ISO 规范没有说明 Hash
排序:它的编写方式使得所有现有 Ruby 实现都自动符合它,而无需更改,即它被编写为 描述性 当前 Ruby 实现,而不是 规范性 。在编写规范时,这些实现包括 MRI、YARV、Rubinius、JRuby、IronRuby、MagLev、MacRuby、XRuby、Ruby.NET、Cardinal、tinyrb、RubyGoLightly、SmallRuby、BlueRuby 等。特别感兴趣的是 MRI(仅 实现 1.8)和 YARV(仅 实现 1.9(当时)),这意味着规范只能指定 1.8 和 1.9 共有的行为,Hash
排序不是。
RubySpec 项目被其开发人员放弃,因为 ruby-核心开发人员和 YARV 开发人员从未认识到它。但是,它确实(隐含地)specify that Hash
literals are ordered left-to-right:
new_hash(1 => 2, 4 => 8, 2 => 4).keys.should == [1, 4, 2]
这是 Hash#keys
的规范,但是,其他规范测试 Hash#values
与 Hash#keys
、Hash#each_value
和 Hash#each_key
具有相同的顺序与那些相同的顺序,Hash#each_pair
和Hash#each
也具有相同的顺序。
我在 the YARV testsuite 中找不到任何指定保留顺序的内容。事实上,我 根本 找不到任何关于在那个测试套件中订购的东西,恰恰相反:测试会花很长的时间 避免 取决于在订购!
Flanagan/matz 书有点隐式地指定 Hash
章节 9.5.3.6 Hash
迭代器 中的文字顺序。首先,它使用与文档大致相同的公式:
In Ruby 1.9, however, hash elements are iterated in their insertion order, […]
但接下来会继续:
[…], and that is the order shown in the following examples:
在那些例子中,实际上使用了文字:
h = { :a=>1, :b=>2, :c=>3 } # The each() iterator iterates [key,value] pairs h.each {|pair| print pair } # Prints "[:a, 1][:b, 2][:c, 3]" # It also works with two block arguments h.each do |key, value| print "#{key}:#{value} " # Prints "a:1 b:2 c:3" end # Iterate over keys or values or both h.each_key {|k| print k } # Prints "abc" h.each_value {|v| print v } # Prints "123" h.each_pair {|k,v| print k,v } # Prints "a1b2c3". Like each
在
h = { a: 1, b: 2 }
is the same ash = { }; h[:a] = 1; h[:b] = 2
并且在
nothing else would make any sense
不幸的是,事实并非如此:
module HashASETWithLogging
def []=(key, value)
puts "[]= was called with [#{key.inspect}] = #{value.inspect}"
super
end
end
class Hash
prepend HashASETWithLogging
end
h = { a: 1, b: 2 }
# prints nothing
h = { }; h[:a] = 1; h[:b] = 2
# []= was called with [:a] = 1
# []= was called with [:b] = 2
因此,根据您如何解读书中的那一行以及您如何 "specification-ish" 判断那本书,是的, 保证了文字的顺序。