在閱讀了Peter Jones 的《Effective Ruby》一書中的Collections一章之后,Set 類似乎提供了一個有趣的 Hash 替代方法。關于 Set 類,Jones 談到:
它很像它的數學表親,一組具有聯合、交集和子集/超集測驗等操作的無序唯一元素的集合。
我唯一關心的是 Set 類是否可能不提供對實際成員物件的直接訪問。
目前,我正在嘗試使用Set(或類似Set)來實作一個簡單的OptionSetAPI,這樣 中的選項OptionSet可能是型別Optionor ValueOption,后者是Option. 這個 API 可能需要訪問存盤在各自集合中的物件OptionSet——無論是存盤在單獨的哈希、陣列、其他容器物件中,還是存盤在OptionSet通過一些繼承的實作中,例如Set作為超類。
我想Set在 內使用OptionSet,或者簡單地OptionSet作為Set. 但是,如果Set可能不提供對成員物件的直接訪問,一旦存盤 - 沒有遍歷 中的每個成員物件Set,直到找到任何表面上的匹配(例如,一旦找到任何Option或ValueOption在集合中,這樣“匹配”就會有一個等效的Option.name,通常是一個符號)-也許有更有效的替代方法?
我會提供示例代碼,但OptionSet目前無法使用。在偽代碼中,我試圖實作OptionSet#getopt(name)為回傳Option存盤在 中的任何命名物件的值,OptionSet如果沒有存盤這樣的選項,則回傳false。
該#getopt方法將呼叫self.getoptObj(name)一個受保護的方法,該方法需要訪問Option集合中命名選項的實際物件。除了那部分實作,否則 Set 可能直接適用。
與 Scheme 類語言相比,Ruby 標準庫本身可能不提供 AssociativeList 類?簡單地說,我想知道是否有任何類Set- 即具有集合論方法的類Set- 但是成員訪問Hash?
更新
我試圖實作一個MappedSet類,至少在偽代碼中,例如使用實體Hash值來存盤一般“鍵”和成員物件之間的映射。但是,我相信這對于 的國際存盤來說是多余的Set。也許我應該簡單地擴展Hash.
uj5u.com熱心網友回復:
如果你想創建一個類似類的哈希,你可以使用 DelegateClass:
class FalsyHash < DelegateClass(Hash)
def initialize(hash)
super.tap { |result| result.default = false }
end
end
irb(main):001:0> f = FalsyHash.new(a: :b)
=> {:a=>:b}
irb(main):002:0> f[:b]
=> false
irb(main):003:0> f.is_a?(Hash)
=> false
這基本上只是一個類,它接受所提供類的一個實體并將其包裝起來,以便轉發方法呼叫。由于它實際上不是 Hash 的實體,我們避免了核心方法檢查我們是否正在處理散列時發生的陷阱,如果我們使用 Hash 的子類,則會發生這種情況。
同樣的事情可以用 Delegator、SimpleDelegator 和 Forwardable 來實作——DelegateClass 只是包裝類的一種直接方式。
您還可以通過使用模塊擴展它們來擴充 Hash 的特定實體:
module Reversable
def reverse
transform_values { |v| v.respond_to?(:reverse) ? v.reverse : v }
end
end
# Guess what this returns for a cookie
{ foo: 'olleH', bar: nil, baz: 'dlrow' }.extend(Reversable)
.reverse
.values
.compact
.sort
.join(" ")
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/348306.html
上一篇:在docker中有分離的網路
