咳といいます。

> どうも。「マイブームつながり」です :-)
> 
> ぼくも WeakRef の機能と仕組みは面白いと思っています。
> 機能としては、永続化機構の Virtual Proxy にも使えそうです。
> 仕組としては、ふつうに参照すると GC で回収されないので、
> id で間接的に参照してますね。こういうトリック好きです。

勉強不足でVirtual Proxyとか用語をよく知らないのですが、
先日の MutexMとキャッシュする参照 CacheRef(未公開・添付)、を
組み合わせると PStore ちっくなのができます。

あと、[ruby-list:23715] の flyaway.rb でちょっと永続化のこと
考えたりしてはみたのですが、なんかこうSQLとしっくりこないんですよねー。

# 全然論理的じゃないですね…。すみません。



# cacheref.rb # # $Id: cacheref.rb,v 1.6 2000/07/04 15:58:05 mas Exp $ # Copyright (c) 2000 Masatoshi SEKI # # cacheref.rb is copyrighted free software by Masatoshi SEKI. # You can redistribute it and/or modify it under the same term as Ruby. require 'weakref' class CacheRef < Delegator def initialize obj = __retrieve__ @ref = WeakRef.new(obj) super(obj) end private def __getobj__ begin begin return @ref[] unless (@__dirty__ || __dirty__) rescue WeakRef::RefError end obj = __retrieve__ @ref = WeakRef.new(obj) return obj ensure @__dirty__ = false end end def __retrieve__ raise NotImplementError, "need to define `__retrieve__'" end def __dirty__ false end public def ref_alive? (!@__dirty__) and (!__dirty__) and @ref.weakref_alive? end def ref_dirty @__dirty__ = true end end
# muref.rb require 'cacheref' require 'mutexm' class Foo < CacheRef include MutexM def initialize(fname) @ctime = nil @fname = fname @folder = nil super() end private def __store__(obj) File.open(@fname, "w+") do |file| Marshal.dump(obj, file) end end def __retrieve__ first = true begin File.open(@fname, "r") do |file| @ctime = file.ctime obj = Marshal.load(file) @__dirty__ = false return obj end rescue Errno::ENOENT, EOFError raise "can not retrieve" unless first first = false __store__({}) retry end end def __dirty__ @ctime != File::ctime(@fname) end def mu_on_lock @folder = __getobj__ end def mu_on_unlock @folder = nil end public def commit in_synchronize __store__(__getobj__) end def transaction synchronize do ref_dirty yield ref_dirty end end end # sample script ... x = Foo.new(ARGV.shift) x['hello'] = 'world' p x x.transaction do x['name'] = 'foo' p x x.commit end x.transaction do x['junk'] = 'junk' p x end # abort p x