有什么好的方法可以将 "array addresses" 传递给方法吗?
Is there a good way to pass "array addresses" to a method?
如何重构以下内容?我有一些值作为嵌套数组存储在我的 YAML 文件中,但我想将我的所有交易拉入两个 get 和 set 方法。这可行,但显然是有限且笨重的。感觉不对。
module Persistance
@store = YAML::Store.new('store.yml')
def self.get_transaction(key)
@store.transaction { @store[key] }
end
def self.get_nested_transaction(key, sub)
@store.transaction { @store[key][sub] }
end
end
额外奖励:我还有一个额外的方法可以增加我的 YAML 文件中的值。有没有进一步的方法来重构这段代码?仅将块传递给单个数据库访问方法是否有意义?
嘿嘿,我记得前阵子在练习PStore的时候就在想这个问题。那时我没有想出一个可行的方法,但我现在设法找到了一个。顺便说一下,yaml/store 很酷,你可以把我介绍给它。
无论如何,继续代码。基本上这里有几个重要的概念:
@store
类似于可以使用 []
和 []=
的散列,但它实际上不是散列,而是 YAML::Store
。
- Ruby 2.3 有一个方法 Hash#dig,这是这里缺失的拼图。您提供一个键列表,它会将每个键视为连续的键。正如我的代码所示,您可以将其用于
get
和 set
,
- 如果
@store
是一个真正的散列,它将结束但不是,所以对于这个答案,我添加了一个 YAML::Store#dig
方法,它与原始方法具有相同的用法。
require 'yaml/store'
class YAML::Store
def dig(*keys)
first_val = self[keys.shift]
if keys.empty?
first_val
else
keys.reduce(first_val) do |result, key|
first_val[key]
end
end
end
end
class YamlStore
attr_reader :store
def initialize filename
@store = YAML::Store.new filename
end
def get *keys
@store.transaction do
@store.dig *keys
end
end
def set *keys, val
@store.transaction do
final_key = keys.pop
hash_to_set = keys.empty? ? @store : @store.dig(*keys)
hash_to_set.send :[]=, final_key, val
end
end
end
filename = 'store.yml'
db = YamlStore.new filename
db.set :a, {}
puts db.get :a
# => {}
db.set :a, :b, 1
puts db.get :a, :b
# => 1
如何重构以下内容?我有一些值作为嵌套数组存储在我的 YAML 文件中,但我想将我的所有交易拉入两个 get 和 set 方法。这可行,但显然是有限且笨重的。感觉不对。
module Persistance
@store = YAML::Store.new('store.yml')
def self.get_transaction(key)
@store.transaction { @store[key] }
end
def self.get_nested_transaction(key, sub)
@store.transaction { @store[key][sub] }
end
end
额外奖励:我还有一个额外的方法可以增加我的 YAML 文件中的值。有没有进一步的方法来重构这段代码?仅将块传递给单个数据库访问方法是否有意义?
嘿嘿,我记得前阵子在练习PStore的时候就在想这个问题。那时我没有想出一个可行的方法,但我现在设法找到了一个。顺便说一下,yaml/store 很酷,你可以把我介绍给它。
无论如何,继续代码。基本上这里有几个重要的概念:
@store
类似于可以使用[]
和[]=
的散列,但它实际上不是散列,而是YAML::Store
。- Ruby 2.3 有一个方法 Hash#dig,这是这里缺失的拼图。您提供一个键列表,它会将每个键视为连续的键。正如我的代码所示,您可以将其用于
get
和set
, - 如果
@store
是一个真正的散列,它将结束但不是,所以对于这个答案,我添加了一个YAML::Store#dig
方法,它与原始方法具有相同的用法。
require 'yaml/store'
class YAML::Store
def dig(*keys)
first_val = self[keys.shift]
if keys.empty?
first_val
else
keys.reduce(first_val) do |result, key|
first_val[key]
end
end
end
end
class YamlStore
attr_reader :store
def initialize filename
@store = YAML::Store.new filename
end
def get *keys
@store.transaction do
@store.dig *keys
end
end
def set *keys, val
@store.transaction do
final_key = keys.pop
hash_to_set = keys.empty? ? @store : @store.dig(*keys)
hash_to_set.send :[]=, final_key, val
end
end
end
filename = 'store.yml'
db = YamlStore.new filename
db.set :a, {}
puts db.get :a
# => {}
db.set :a, :b, 1
puts db.get :a, :b
# => 1