Christopher Dicely wrote in post #995252:
I want pstore to be able to do same thing. I've included Enumerable but
I do have to implement the each method which I dont know how to go
about. Any suggestions? Thanks
Regarding your original code
h = {0 => "sword", 5 => "hammer", 3 => "arrow"}
puts h.map{ |x| x[0]}.max # gives the highest key which is 5
With a Hash I'd rather
irb(main):002:0> h.keys.max
=> 5
irb(main):003:0> h.max_by {|k,v| k}.first
=> 5
It looks like, during a transaction, the content of a PStore is
represent by a Hash in the instance variable @table, so you if you
want the PStore to act like a Hash, something like this should work:
class PStore
def each &blk
in_transaction
@table.each &blk
end
end
(If you call this without a block, it looks like you get an enumerator
over the state of the store as of the transaction it was captured in,
which can be used outside of that transaction, and that could be
useful for some things.)
Obviously, this is exploiting details of the implementation rather
than the public interface, so it's at more risk of getting broken in a
new version of the library than would be an approach that relies only
on the public interface.
Thanks. I didnt realized before that opening up a class would give you
access to instance variables as well. I tried to access the table
variable before using self.table but there was no getter method defined
for it so I had a bit of trouble.
Good catch on - being able to get enum and use it outside transaction.
Btw, I find having to do everything in transaction quite annoying and
tedious. Do you see any better way of implementing it instead of always
passing a block to transaction()?
If you do not want to use transactions you can as well just write a
Hash with Marshal and not use PStore at all. Transaction safety and
persistent consistency is the main feature to use PStore.
A proper implementation of Hash like access that would not depend on
the internals could roughly work like this:
# untested!
class PStoreHash
attr_accessor :read_only
def initialize(ps, read_only = false)
@ps = ps
@read_only = read_only
end
def method_missing(*a,&b)
@ps.transaction read_only do |ps|
PSWrap.new(ps).send(*a,&b)
end
end
class PSWrap < SimpleDelegator
include Enumerable
def keys; roots; end
def values; roots.map {|r| self[r]}; end
def each
if block_given?
roots.each {|r| yield r, self[r]}
self
else
to_a
end
end
end
end
Kind regards
robert
···
On Wed, Apr 27, 2011 at 8:08 AM, Reginald Tan <redge.tan@gmail.com> wrote:
On Tue, Apr 26, 2011 at 6:34 PM, Reginald Tan <redge.tan@gmail.com> >> wrote:
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/