[#6143] — Christophe Poucet <christophe.poucet@...>

Hello,

17 messages 2005/10/04
[#6147] Re: patch.tgz — nobu.nokada@... 2005/10/04

Hi,

[#6199] Kernel rdoc HTML file not being created when rdoc is run on 1.8.3 — James Britt <ruby@...>

When 1.8.3 came out, I grabbed the source and ran rdoc on it. After

9 messages 2005/10/08

[#6251] RubyGems, upstream releases and idempotence of packaging — Mauricio Fern疣dez <mfp@...>

[sorry for the very late reply; I left this message in +postponed and forgot

14 messages 2005/10/12

[#6282] Wilderness: Need Code to invoke ELTS_SHARED response — "Charles E. Thornton" <ruby-core@...>

Testing the My Object Dump and I am trying to cause creation

13 messages 2005/10/14
[#6283] Re: Wilderness: Need Code to invoke ELTS_SHARED response — Mauricio Fern疣dez <mfp@...> 2005/10/14

On Fri, Oct 14, 2005 at 05:04:59PM +0900, Charles E. Thornton wrote:

[#6288] Re: Wilderness: Need Code to invoke ELTS_SHARED response — "Charles E. Thornton" <ruby-core@...> 2005/10/14

Mauricio Fern疣dez wrote:

[#6365] Time for built-in Rational and Complex classes? — Gavin Sinclair <gsinclair@...>

There has been some support for, but no comment on, RCR #260 ("Make

12 messages 2005/10/24
[#6366] Re: Time for built-in Rational and Complex classes? — "Ara.T.Howard" <Ara.T.Howard@...> 2005/10/24

On Mon, 24 Oct 2005, Gavin Sinclair wrote:

[#6405] Re: [PATCH] Pathname.exists?() — "Berger, Daniel" <Daniel.Berger@...>

12 messages 2005/10/25
[#6406] Re: [PATCH] Pathname.exists?() — TRANS <transfire@...> 2005/10/25

On 10/25/05, Berger, Daniel <Daniel.Berger@qwest.com> wrote:

[#6408] Re: [PATCH] Pathname.exists?() — Gavin Sinclair <gsinclair@...> 2005/10/25

On 10/26/05, TRANS <transfire@gmail.com> wrote:

[#6442] Wilderness: I Have formatted README.EXT into an HTML Document — "Charles E. Thornton" <ruby-core@...>

I have taken README.EXT (English Version Only) and have reformatted

14 messages 2005/10/27

[#6469] csv.rb a start on refactoring. — Hugh Sasse <hgs@...>

For a database application I found using CSV to be rather slow.

50 messages 2005/10/28
[#6470] Re: csv.rb a start on refactoring. — "Ara.T.Howard" <Ara.T.Howard@...> 2005/10/28

[#6471] Re: csv.rb a start on refactoring. — James Edward Gray II <james@...> 2005/10/28

On Oct 28, 2005, at 8:53 AM, Ara.T.Howard wrote:

[#6474] Re: csv.rb a start on refactoring. — "Ara.T.Howard" <Ara.T.Howard@...> 2005/10/28

On Fri, 28 Oct 2005, James Edward Gray II wrote:

[#6484] Re: csv.rb a start on refactoring. — James Edward Gray II <james@...> 2005/10/29

On Oct 28, 2005, at 9:58 AM, Ara.T.Howard wrote:

[#6485] Re: csv.rb a start on refactoring. — "Ara.T.Howard" <Ara.T.Howard@...> 2005/10/29

On Sat, 29 Oct 2005, James Edward Gray II wrote:

[#6486] Re: csv.rb a start on refactoring. — James Edward Gray II <james@...> 2005/10/29

On Oct 28, 2005, at 8:25 PM, Ara.T.Howard wrote:

[#6487] Re: csv.rb a start on refactoring. — "Ara.T.Howard" <Ara.T.Howard@...> 2005/10/29

On Sat, 29 Oct 2005, James Edward Gray II wrote:

[#6491] Re: csv.rb a start on refactoring. — James Edward Gray II <james@...> 2005/10/29

On Oct 28, 2005, at 8:43 PM, Ara.T.Howard wrote:

[#6493] Re: csv.rb a start on refactoring. — James Edward Gray II <james@...> 2005/10/29

On Oct 28, 2005, at 10:06 PM, James Edward Gray II wrote:

[#6496] Re: csv.rb a start on refactoring. — "Ara.T.Howard" <Ara.T.Howard@...> 2005/10/29

On Sun, 30 Oct 2005, James Edward Gray II wrote:

[#6502] Re: csv.rb a start on refactoring. — James Edward Gray II <james@...> 2005/10/30

On Oct 29, 2005, at 12:11 PM, Ara.T.Howard wrote:

[#6505] Re: csv.rb a start on refactoring. — "Ara.T.Howard" <Ara.T.Howard@...> 2005/10/30

On Mon, 31 Oct 2005, James Edward Gray II wrote:

[#6511] Planning FasterCSV (was Re: csv.rb a start on refactoring.) — James Edward Gray II <james@...> 2005/10/30

I've decided to create a FasterCSV library, based on the code we

[#6516] Re: Planning FasterCSV (was Re: csv.rb a start on refactoring.) — "Ara.T.Howard" <Ara.T.Howard@...> 2005/10/31

On Mon, 31 Oct 2005, James Edward Gray II wrote:

[#6518] Re: Planning FasterCSV (was Re: csv.rb a start on refactoring.) — "NAKAMURA, Hiroshi" <nakahiro@...> 2005/10/31

-----BEGIN PGP SIGNED MESSAGE-----

Re: [PATCH] PStore Documentation

From: James Edward Gray II <james@...>
Date: 2005-10-26 21:37:27 UTC
List: ruby-core #6434
On Oct 26, 2005, at 4:03 PM, Daniel Berger wrote:

> A couple corrections & suggestions:

[snip excellent feedback]

Thank you for taking the time to look over this.  I go a little cross- 
eyed after messing with these for a while.  I do try to find errors,  
but it's obvious I miss some.

The attached patch incorporates all your changes and suggestions,  
except...

> Also, I think we ought to get rid of the "if $0 == __FILE__" code.   
> Or do people really use that?

That, which is not a documentation issue and thus none of my  
business.  ;)

James Edward Gray II

Attachments (1)

pstore_docs.diff (10.2 KB, text/x-diff)
Index: lib/.document
===================================================================
RCS file: /src/ruby/lib/.document,v
retrieving revision 1.1.2.7
diff -u -r1.1.2.7 .document
--- lib/.document	25 Oct 2005 06:38:26 -0000	1.1.2.7
+++ lib/.document	26 Oct 2005 21:32:58 -0000
@@ -25,6 +25,7 @@
 observer.rb
 optionparser.rb
 pathname.rb
+pstore.rb
 rational.rb
 set.rb
 shellwords.rb
Index: lib/pstore.rb
===================================================================
RCS file: /src/ruby/lib/pstore.rb,v
retrieving revision 1.17.2.3
diff -u -r1.17.2.3 pstore.rb
--- lib/pstore.rb	27 Oct 2004 09:16:20 -0000	1.17.2.3
+++ lib/pstore.rb	26 Oct 2005 21:32:58 -0000
@@ -1,24 +1,91 @@
+# = PStore -- Transactional File Storage for Ruby Objects
 #
-# How to use:
+# pstore.rb -
+#   by unknown
+#   documentation by Kev Jackson and James Edward Gray II
 #
-# db = PStore.new("/tmp/foo")
-# db.transaction do
-#   p db.roots
-#   ary = db["root"] = [1,2,3,4]
-#   ary[0] = [1,1.5]
-# end
-
-# db.transaction do
-#   p db["root"]
-# end
+# See PStore for documentation.
+
 
 require "fileutils"
 require "digest/md5"
 
+#
+# PStore implements a file based persistance mechanism based on a Hash.  User
+# code can store hierarchies of Ruby objects (values) into the data store file
+# by name (keys).  An object hierarchy may be just a single object.  User code 
+# may later read values back from the data store or even update data, as needed.
+# 
+# The transactional behavior ensures that any changes succeed or fail together.
+# This can be used to ensure that the data store is not left in a transitory
+# state, where some values were upated but others were not.
+# 
+# Behind the scenes, Ruby objects are stored to the data store file with 
+# Marshal.  That carries the usual limitations.  Proc objects cannot be 
+# marshalled, for example.
+#
+# == Usage example:
+# 
+#  require "pstore"
+#  
+#  # a mock wiki object...
+#  class WikiPage
+#    def initialize( page_name, author, contents )
+#      @page_name = page_name
+#      @revisions = Array.new
+#      
+#      add_revision(author, contents)
+#    end
+#    
+#    attr_reader :page_name
+#    
+#    def add_revision( author, contents )
+#      @revisions << { :created  => Time.now,
+#                      :author   => author,
+#                      :contents => contents }
+#    end
+#    
+#    def wiki_page_references
+#      [@page_name] + @revisions.last[:contents].scan(/\b(?:[A-Z]+[a-z]+){2,}/)
+#    end
+#    
+#    # ...
+#  end
+#  
+#  # create a new page...
+#  home_page = WikiPage.new( "HomePage", "James Edward Gray II",
+#                            "A page about the JoysOfDocumentation..." )
+#  
+#  # then we want to update page data and the index together, or not at all...
+#  wiki = PStore.new("wiki_pages.pstore")
+#  wiki.transaction do  # begin transaction; do all of this or none of it
+#    # store page...
+#    wiki[home_page.page_name] = home_page
+#    # ensure that an index has been created...
+#    wiki[:wiki_index] ||= Array.new
+#    # update wiki index...
+#    wiki[:wiki_index].push(*home_page.wiki_page_references)
+#  end                   # commit changes to wiki data store file
+#  
+#  ### Some time later... ###
+#  
+#  # read wiki data...
+#  wiki.transaction(true) do  # begin read-only transaction, no changes allowed
+#    wiki.roots.each do |data_root_name|
+#      p data_root_name
+#      p wiki[data_root_name]
+#    end
+#  end
+#
 class PStore
+  # The error type thrown by all PStore methods.
   class Error < StandardError
   end
 
+  # 
+  # To construct a PStore object, pass in the _file_ path where you would like 
+  # the data to be stored.
+  # 
   def initialize(file)
     dir = File::dirname(file)
     unless File::directory? dir
@@ -32,19 +99,41 @@
     @abort = false
   end
 
+  # Raises PStore::Error if the calling code is not in a PStore#transaction.
   def in_transaction
     raise PStore::Error, "not in transaction" unless @transaction
   end
+  # 
+  # Raises PStore::Error if the calling code is not in a PStore#transaction or
+  # if the code is in a read-only PStore#transaction.
+  # 
   def in_transaction_wr()
     in_transaction()
     raise PStore::Error, "in read-only transaction" if @rdonly
   end
   private :in_transaction, :in_transaction_wr
 
+  #
+  # Retrieves a value from the PStore file data, by _name_.  The hierarchy of 
+  # Ruby objects stored under that root _name_ will be returned.
+  # 
+  # *WARNING*:  This method is only valid in a PStore#transaction.  It will
+  # raise PStore::Error if called at any other time.
+  #
   def [](name)
     in_transaction
     @table[name]
   end
+  #
+  # This method is just like PStore#[], save that you may also provide a 
+  # _default_ value for the object.  In the event the specified _name_ is not 
+  # found in the data store, your _default_ will be returned instead.  If you do 
+  # not specify a default, PStore::Error will be raised if the object is not 
+  # found.
+  # 
+  # *WARNING*:  This method is only valid in a PStore#transaction.  It will
+  # raise PStore::Error if called at any other time.
+  #
   def fetch(name, default=PStore::Error)
     unless @table.key? name
       if default==PStore::Error
@@ -55,39 +144,138 @@
     end
     self[name]
   end
+  #
+  # Stores an individual Ruby object or a hierarchy of Ruby objects in the data
+  # store file under the root _name_.  Assigning to a _name_ already in the data
+  # store clobbers the old data.
+  # 
+  # == Example:
+  # 
+  #  require "pstore"
+  #  
+  #  store = PStore.new("data_file.pstore")
+  #  store.transaction do  # begin transaction
+  #    # load some data into the store...
+  #    store[:single_object] = "My data..."
+  #    store[:obj_heirarchy] = { "Kev Jackson" => ["rational.rb", "pstore.rb"],
+  #                              "James Gray"  => ["erb.rb", "pstore.rb"] }
+  #  end                   # commit changes to data store file
+  # 
+  # *WARNING*:  This method is only valid in a PStore#transaction and it cannot
+  # be read-only.  It will raise PStore::Error if called at any other time.
+  #
   def []=(name, value)
     in_transaction_wr()
     @table[name] = value
   end
+  #
+  # Removes an object hierarchy from the data store, by _name_.
+  # 
+  # *WARNING*:  This method is only valid in a PStore#transaction and it cannot
+  # be read-only.  It will raise PStore::Error if called at any other time.
+  #
   def delete(name)
     in_transaction_wr()
     @table.delete name
   end
 
+  #
+  # Returns the names of all object hierarchies currently in the store.
+  # 
+  # *WARNING*:  This method is only valid in a PStore#transaction.  It will
+  # raise PStore::Error if called at any other time.
+  #
   def roots
     in_transaction
     @table.keys
   end
+  #
+  # Returns true if the supplied _name_ is currently in the data store.
+  # 
+  # *WARNING*:  This method is only valid in a PStore#transaction.  It will
+  # raise PStore::Error if called at any other time.
+  #
   def root?(name)
     in_transaction
     @table.key? name
   end
+  # Returns the path to the data store file.
   def path
     @filename
   end
 
+  #
+  # Ends the current PStore#transaction, committing any changes to the data
+  # store immediately.
+  # 
+  # == Example:
+  # 
+  #  require "pstore"
+  #   
+  #  store = PStore.new("data_file.pstore")
+  #  store.transaction do  # begin transaction
+  #    # load some data into the store...
+  #    store[:one] = 1
+  #    store[:two] = 2
+  #  
+  #    store.commit        # end transaction here, committing changes
+  #  
+  #    store[:three] = 3   # this change is never reached
+  #  end
+  # 
+  # *WARNING*:  This method is only valid in a PStore#transaction.  It will
+  # raise PStore::Error if called at any other time.
+  #
   def commit
     in_transaction
     @abort = false
     throw :pstore_abort_transaction
   end
+  #
+  # Ends the current PStore#transaction, discarding any changes to the data
+  # store.
+  # 
+  # == Example:
+  # 
+  #  require "pstore"
+  #   
+  #  store = PStore.new("data_file.pstore")
+  #  store.transaction do  # begin transaction
+  #    store[:one] = 1     # this change is not applied, see below...
+  #    store[:two] = 2     # this change is not applied, see below...
+  #  
+  #    store.abort         # end transaction here, discard all changes
+  #  
+  #    store[:three] = 3   # this change is never reached
+  #  end
+  # 
+  # *WARNING*:  This method is only valid in a PStore#transaction.  It will
+  # raise PStore::Error if called at any other time.
+  #
   def abort
     in_transaction
     @abort = true
     throw :pstore_abort_transaction
   end
 
-  def transaction(read_only=false)
+  #
+  # Opens a new transaction for the data store.  Code executed inside a block
+  # passed to this method may read and write data to and from the data store 
+  # file.
+  # 
+  # At the end of the block, changes are committed to the data store
+  # automatically.  You may exit the transaction early with a call to either 
+  # PStore#commit or PStore#abort.  See those methods for details about how
+  # changes are handled.  Raising an uncaught Exception in the block is 
+  # equivalent to calling PStore#abort.
+  # 
+  # If _read_only_ is set to +true+, you will only be allowed to read from the
+  # data store during the transaction and any attempts to change the data will
+  # raise a PStore::Error.
+  # 
+  # Note that PStore does not support nested transactions.
+  #
+  def transaction(read_only=false)  # :yields:  pstore
     raise PStore::Error, "nested transaction" if @transaction
     begin
       @rdonly = read_only
@@ -155,19 +343,23 @@
     value
   end
 
-  def dump(table)
+  # This method is just a wrapped around Marshal.dump.
+  def dump(table)  # :nodoc:
     Marshal::dump(table)
   end
 
-  def load(content)
+  # This method is just a wrapped around Marshal.load.
+  def load(content)  # :nodoc:
     Marshal::load(content)
   end
 
-  def load_file(file)
+  # This method is just a wrapped around Marshal.load.
+  def load_file(file)  # :nodoc:
     Marshal::load(file)
   end
 
   private
+  # Commits changes to the data store file.
   def commit_new(f)
     f.truncate(0)
     f.rewind
@@ -180,6 +372,8 @@
   end
 end
 
+# :enddoc:
+
 if __FILE__ == $0
   db = PStore.new("/tmp/foo")
   db.transaction do

In This Thread