[前][次][番号順一覧][スレッド一覧]

ruby-changes:72393

From: BurdetteLamar <ko1@a...>
Date: Sat, 2 Jul 2022 21:49:25 +0900 (JST)
Subject: [ruby-changes:72393] 8715ecd04b (master): [ruby/pstore] Enhanced RDoc

https://git.ruby-lang.org/ruby.git/commit/?id=8715ecd04b

From 8715ecd04b8bb4976b89913be4e790e5d15c4b74 Mon Sep 17 00:00:00 2001
From: BurdetteLamar <BurdetteLamar@Y...>
Date: Mon, 27 Jun 2022 13:16:58 -0500
Subject: [ruby/pstore] Enhanced RDoc

https://github.com/ruby/pstore/commit/81a266d88c
---
 lib/pstore.rb | 497 ++++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 343 insertions(+), 154 deletions(-)

diff --git a/lib/pstore.rb b/lib/pstore.rb
index a46bcb84bc..177f1b2dfc 100644
--- a/lib/pstore.rb
+++ b/lib/pstore.rb
@@ -10,87 +10,268 @@ https://github.com/ruby/ruby/blob/trunk/lib/pstore.rb#L10
 
 require "digest"
 
+# An instance of class \PStore can store and retrieve Ruby objects --
+# not just strings or raw data, but objects of many kinds.
+# There are three key terms here (details at the links):
 #
-# PStore implements a file based persistence 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.
+# - {Store}[rdoc-ref:PStore@The+Store]: a store is an instance of \PStore.
+# - {Roots}[rdoc-ref:PStore@Roots]: the store is hash-like;
+#   each root is a key for a stored object.
+# - {Transactions}[rdoc-ref:PStore@Transactions]: each transaction is a ollection
+#   of prospective changes to the store;
+#   a transaction is defined in the block given with a call
+#   to PStore#transaction.
 #
-# 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 updated but others were not.
+# == About the Examples
 #
-# 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.
+# All examples on this page assume that the following code has been executed:
 #
-# == Usage example:
+#   require 'pstore'
+#   # Create a store with file +flat.store+.
+#   store = PStore.new('flat.store')
+#   # Store some objects.
+#   store.transaction do
+#     store[:foo] = 0
+#     store[:bar] = 1
+#     store[:baz] = 2
+#   end
+#
+# To avoid modifying the example store, some examples first execute
+# <tt>temp = store.dup</tt>, then apply changes to +temp+
+#
+# == The Store
+#
+# The contents of the store are maintained in a file whose path is specified
+# when the store is created (see PStore.new):
+#
+# - Ruby objects put into the store are serialized as string data
+#   and written to the file;
+# - Data retrieved from the store is read from the file and deserialized
+#   to form Ruby objects.
+#
+# The objects are serialized and deserialized using
+# module Marshal, which means that certain objects cannot be added to the store;
+# see {Marshal::dump}[https://docs.ruby-lang.org/en/master/Marshal.html#method-c-dump].
+#
+# == Roots
+#
+# A store may have any number of entries, called _roots_.
+# Each root has a key and a value, just as in a hash:
+#
+# - Key: as in a hash, the key can be (almost) any object;
+#   see {Hash}[https://docs.ruby-lang.org/en/master/Hash.html].
+#   You may find it convenient to keep it simple by using only
+#   symbols or strings as keys.
+# - Value: the value truly may be any object, and in fact can be a collection
+#   (e.g., an array, a hash, a set, a range, etc).
+#   That collection may in turn contain nested collections, to any depth.
+#   See {Deep Root Values}[rdoc-ref:PStore@Deep+Root+Values].
+#
+# == Transactions
+#
+# A call to PStore#transaction must have a block.
+#
+# A transaction consists of just those \PStore method calls in the block
+# that would modify the store; those methods are #[]= and #delete.
+# Note that the block may contain any code whatsoever
+# except a nested call to #transaction.
+#
+# An instance method in \PStore may be called only from within a transaction
+# (with the exception the #path may be called from anywhere).
+# This assures that the call is executed only when the store is secure and stable.
+#
+# When the transaction block exits,
+# the specified changes are made automatically.
+# (and atomically; that is, either all changes are posted, or none are).
+#
+# Exactly how the changes are posted
+# depends on the value of attribute #ultra_safe (details at the link).
+#
+# The block may be exited early by calling method #commit or #abort.
+#
+# - Method #commit triggers the update to the store and exits the block:
+#
+#     temp = store.dup
+#     temp.transaction do
+#       temp.roots # => [:foo, :bar, :baz]
+#       temp[:bat] = 3
+#       temp.commit
+#       fail 'Cannot get here'
+#     end
+#     temp.transaction do
+#       # Update was completed.
+#       store.roots # => [:foo, :bar, :baz, :bat]
+#     end
+#
+# - Method #abort discards the update to the store and exits the block:
+#
+#     store.transaction do
+#       store[:bam] = 4
+#       store.abort
+#       fail 'Cannot get here'
+#     end
+#     store.transaction do
+#       # Update was not completed.
+#       store[:bam] # => nil
+#     end
+#
+# Each transaction is either:
+#
+# - Read-write (the default):
+#
+#     store.transaction do
+#       # Read-write transaction.
+#       # Any code except a call to #transaction is allowed here.
+#     end
+#
+# - Read-only (optional argument +read_only+ set to +true+):
+#
+#     store.transaction(true) do
+#       # Read-only transaction:
+#       # Calls to #transaction, #[]=, and #delete are not allowed here.
+#     end
+#
+# == Deep Root Values
+#
+# The value for a root may be a simple object (as seen above).
+# It may also be a hierarchy of objects nested to any depth:
+#
+#   deep_store = PStore.new('deep.store')
+#   deep_store.transaction do
+#     array_of_hashes = [{}, {}, {}]
+#     deep_store[:array_of_hashes] = array_of_hashes
+#     deep_store[:array_of_hashes] # => [{}, {}, {}]
+#     hash_of_arrays = {foo: [], bar: [], baz: []}
+#     deep_store[:hash_of_arrays] = hash_of_arrays
+#     deep_store[:hash_of_arrays]  # => {:foo=>[], :bar=>[], :baz=>[]}
+#     deep_store[:hash_of_arrays][:foo].push(:bat)
+#     deep_store[:hash_of_arrays]  # => {:foo=>[:bat], :bar=>[], :baz=>[]}
+#   end
+#
+# And recall that you can use
+# {dig methods}[https://docs.ruby-lang.org/en/master/dig_methods_rdoc.html]
+# in a returned hierarchy of objects.
+#
+# == Working with the Store
+#
+# === Creating a Store
+#
+# Use method PStore.new to create a store.
+# The new store creates or opens its containing file:
+#
+#   store = PStore.new('t.store')
+#
+# === Modifying the Store
+#
+# Use method #[]= to update or create a root:
+#
+#   temp = store.dup
+#   temp.transaction do
+#     temp[:foo] = 1 # Update.
+#     temp[:bam] = 1 # Create.
+#   end
+#
+# Use method #delete to remove a root:
+#
+#   temp = store.dup
+#   temp.transaction do
+#     temp.delete(:foo)
+#     temp[:foo] # => nil
+#   end
+#
+# === Retrieving Stored Objects
+#
+# Use method #fetch (allows default) or #[] (defaults to +nil+)
+# to retrieve a root:
+#
+#   store.transaction do
+#     store[:foo]             # => 0
+#     store[:nope]            # => nil
+#     store.fetch(:baz)       # => 2
+#     store.fetch(:nope, nil) # => nil
+#     store.fetch(:nope)      # Raises exception.
+#   end
+#
+# === Querying the Store
+#
+# Use method #root? to determine whether a given root exists:
+#
+#   store.transaction do
+#     store.root?(:foo) # => true.
+#   end
+#
+# Use method #roots to retrieve root keys:
+#
+#   store.transaction do
+#     store.roots # => [:foo, :bar, :baz].
+#   end
+#
+# Use method #path to retrieve the path to the store's underlying file:
+#
+#   store.transaction do
+#     store.path # => "flat.store"
+#   end
+#
+# == Transaction Safety
+#
+# For transaction safety, see:
+#
+# - Optional argument +thread_safe+ at method PStore.new.
+# - Attribute #ultra_safe.
+#
+# Needless to say, if you're storing valuable data with \PStore, then you should
+# backup the \PStore file from time to time.
+#
+# == An Example Store
 #
 #  require "pstore"
 #
-#  # a mock wiki object...
+#  # A mock wiki object.
 #  class WikiPage
-#    def initialize( page_name, author, contents )
+#
+#    attr_reader :page_name
+#
+#    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 }
+#    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..." )
+#  # Create a new wiki 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...
+#  # Update page data and the index together, or not at all.
+#  wiki.transaction do
+#    # Store page.
 #    wiki[home_page.page_name] = home_page
-#    # ensure that an index has been created...
+#    # Create page index.
 #    wiki[:wiki_index] ||= Array.new
-#    # update wiki index...
+#    # Update wiki index.
 #    wiki[:wiki_index].push(*home_page.wiki_page_references)
-#  end          (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]