Ruby,从v1开始.9,在通过散列循环时支持确定性顺序;首先添加的条目将首先返回.

这是否适用于文字,即{ a: 1, b: 2 }总是在b之前产生a?

我用Ruby 2.1(MRI)做了一个快速的实验,事实上它是一致的,但是语言在多大程度上保证了它能在所有Ruby实现上工作?

推荐答案

有几个地方可以指定这个could,也就是说,有几个地方被认为是"Ruby语言规范":

ISO规范没有提到任何关于Hash次排序的内容:它的编写方式是,所有现有的Ruby实现都自动符合它,而无需进行更改,也就是说,它被编写为当前Ruby实现的descriptive次,而不是prescriptive次.在编写规范时,这些实现包括MRI、YARV、Rubinius、JRuby、IronRuby、MagLev、MacRuby、XRuby、Ruby.NET、Cardinal、tinyrb、RubyGollightly、SmallRuby、BlueRuby等.特别令人感兴趣的是MRI(only实现了1.8)和YARV(only实现了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#keysHash#each_valueHash#each_key的顺序相同,Hash#each_pairHash#each的顺序也相同.

我在the YARV testsuite中找不到任何指定保留顺序的内容.事实上,在这个测试套件中,我找不到任何关于排序的at all,恰恰相反:根据排序,测试的长度可以达到avoid

Flanagan/matz的书在第9.5.3.6 100 iterators节中隐式地指定了Hash个文字顺序.首先,它使用了与文档基本相同的公式:

然而,在Ruby 1.9中,哈希元素按插入顺序进行迭代,[…]

但接下来:

[…],这是以下示例中显示的顺序:

在这些例子中,它使用了一个文字:

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 short84_31418673">his comment年,@mu is too short提到了这一点

h = { a: 1, b: 2 }等于h = { }; h[:a] = 1; h[:b] = 2

another comment年后

其他一切都毫无意义

不幸的是,事实并非如此:

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

所以,取决于你如何解读这本书中的这句话,取决于你如何判断这本书,是的,文字的顺序是is.

Ruby相关问答推荐

运行跳过的RSpec测试,如果通过则失败

Ruby脚本递归地创建深度嵌套的目录

Ruby 扁平化 JSON 对象或哈希

使用 Ruby 仅删除数组中的特定重复项

为什么我的二维 Ruby 数组的多个值会发生变化,尽管只更改了其中一个?

在 Ruby 中,如何编写一个可以与 &:symbol 一起使用的简单方法?

Ruby 匹配第一次出现的字符串以进行 gsub 替换

Ruby 局部变量未定义

Ruby 中的字符串是可变的吗?

按键对哈希进行分组并对值求和

我应该在我的 ruby​​ 脚本中定义一个 main 方法吗?

Ruby注入初始为哈希

rails 控制台、RVM 和 readline 的问题

获取下周一(或一周中的任何一天)的日期的 Ruby 代码

在本地覆盖 Vagrant 配置设置(每个开发人员)

to_proc 方法是什么意思?

是否可以使用 Ruby 读取文件的修改日期?

如何使用 Ruby 运行命令五次?

将哈希传递给函数 ( *args ) 及其含义

将字符串与Ruby中的数字连接起来