允许Ruby 1.9的哈希语法?

虽然我已经使用Ruby 1.9了一段时间,但我最近才发现现在支持的更新的哈希语法:

settings = { host: "localhost", port: 5984 } 

相反:

 settings = { "host" => "localhost" } 

我喜欢它与JavaScript的对象符号的相似性,看起来有点像JSON,所以我可能会切换到使用它与我的所有库,但我仍然希望支持其他用户和我自己的项目,它们采用旧的语法。

所以它真的归结为一个相当简单的问题,即必须测试符号和字符串。 有没有一种简单的方法可以将这两条线作为一条线?

 return true if settings["host"] and settings["db"] return true if settings[:host] and settings[:db] 

即使在Ruby <1.9中,您也可以使用符号作为键。 例如:

 # Ruby 1.8.7 settings = { :host => "localhost" } puts settings[:host] #outputs localhost settings.keys[0].class # => Symbol 

Ruby 1.9改变了创建哈希的方式。 它需要密钥并将其转换为符号,同时不需要哈希火箭。

 # Ruby 1.9.2 settings = { host: "localhost" } settings[:host] # => "localhost" settings.keys[0].class # => Symbol 

在这两种情况下,如果我尝试使用settings["name"]访问settings[:name] settings["name"] ,我将会变为零。 所有Ruby 1.9都允许创建哈希的新方法。 要回答您的问题,据我所知,如果您想要向后兼容Ruby 1.8,则不能使用新的{key: value}语法。

ActiveSupport(来自Rails)提供HashWithIndifferentAccess 。 您需要明确使用它而不是标准Hash。

请注意,该类本身的引用:

这个类有可疑的语义,我们只有这样才能让人们写params [:key]而不是params [‘key’],并且它们对两个键都有相同的值。

所以它真的归结为一个相当简单的问题,即必须测试符号和字符串。 有没有一种简单的方法可以将这两条线作为一条线?

 return true if settings["host"] and settings["db"] return true if settings[:host] and settings[:db] 

我不确定你真正在问什么,因为这似乎与原始标题完全无关,但请尝试:

 # somewhere you get the values you are going to need to look up... host = 'foo' db = 'bar' # then code goes by... return true if settings[host.to_sym] and settings[db.to_sym] # later you assign a symbol to one of the keys: host = :foo # more code goes by... return true if settings[host.to_sym] and settings[db.to_sym] 

这都一样。 让Ruby根据需要从字符串转换为符号。

这是因为:

 'foo'.to_s # => "foo" :foo.to_s # => "foo" 'foo'.to_sym # => :foo :foo.to_sym # => :foo 

您选择是否要使用符号或字符串作为哈希键,并让Ruby对其进行排序。