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.
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.
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.
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
By default, file integrity is only ensured as long as the operating system (and the underlying hardware) doesn’t raise any unexpected I/O errors. If an I/O error occurs while PStore
is writing to its file, then the file will become corrupted.
You can prevent this by setting pstore.ultra_safe = true. However, this results in a minor performance loss, and only works on platforms that support atomic file renames. Please consult the documentation for ultra_safe
for details.
Needless to say, if you’re storing valuable data with PStore
, then you should backup the PStore
files from time to time.
Raised when attempting to convert special float values (in particular Infinity
or NaN
) to numerical classes which don’t support them.
Float::INFINITY.to_r #=> FloatDomainError: Infinity
The global value true
is the only instance of class TrueClass
and represents a logically true value in boolean expressions. The class provides operators allowing true
to be used in logical expressions.
This module provides a framework for message digest libraries.
You may want to look at OpenSSL::Digest
as it supports more algorithms.
A cryptographic hash function is a procedure that takes data and returns a fixed bit string: the hash value, also known as digest. Hash
functions are also called one-way functions, it is easy to compute a digest from a message, but it is infeasible to generate a message from a digest.
require 'digest' # Compute a complete digest Digest::SHA256.digest 'message' #=> "\xABS\n\x13\xE4Y..." sha256 = Digest::SHA256.new sha256.digest 'message' #=> "\xABS\n\x13\xE4Y..." # Other encoding formats Digest::SHA256.hexdigest 'message' #=> "ab530a13e459..." Digest::SHA256.base64digest 'message' #=> "q1MKE+RZFJgr..." # Compute digest by chunks md5 = Digest::MD5.new md5.update 'message1' md5 << 'message2' # << is an alias for update md5.hexdigest #=> "94af09c09bb9..." # Compute digest for a file sha256 = Digest::SHA256.file 'testfile' sha256.hexdigest
Additionally digests can be encoded in “bubble babble” format as a sequence of consonants and vowels which is more recognizable and comparable than a hexadecimal digest.
require 'digest/bubblebabble' Digest::SHA256.bubblebabble 'message' #=> "xopoh-fedac-fenyh-..."
See the bubble babble specification at web.mit.edu/kenta/www/one/bubblebabble/spec/jrtrjwzi/draft-huima-01.txt.
Digest
algorithms Different digest algorithms (or hash functions) are available:
MD5
See RFC 1321 The MD5
Message-Digest Algorithm
As Digest::RMD160
. See homes.esat.kuleuven.be/~bosselae/ripemd160.html.
SHA1
See FIPS 180 Secure Hash
Standard.
SHA2
family
See FIPS 180 Secure Hash
Standard which defines the following algorithms:
SHA512
SHA384
SHA256
The latest versions of the FIPS publications can be found here: csrc.nist.gov/publications/PubsFIPS.html.
The Readline
module provides interface for GNU Readline
. This module defines a number of methods to facilitate completion and accesses input history from the Ruby interpreter. This module supported Edit Line(libedit) too. libedit is compatible with GNU Readline
.
Reads one inputted line with line edit by Readline.readline
method. At this time, the facilitatation completion and the key bind like Emacs can be operated like GNU Readline
.
require "readline" while buf = Readline.readline("> ", true) p buf end
The content that the user input can be recorded to the history. The history can be accessed by Readline::HISTORY
constant.
require "readline" while buf = Readline.readline("> ", true) p Readline::HISTORY.to_a print("-> ", buf, "\n") end
Documented by Kouji Takao <kouji dot takao at gmail dot com>.
FileTest
implements file test operations similar to those used in File::Stat
. It exists as a standalone module, and its methods are also insinuated into the File
class. (Note that this is not done by inclusion: the interpreter cheats).
Include the English
library file in a Ruby script, and you can reference the global variables such as $_
using less cryptic names, listed below.
Without ‘English’:
$\ = ' -- ' "waterbuffalo" =~ /buff/ print $', $$, "\n"
With English:
require "English" $OUTPUT_FIELD_SEPARATOR = ' -- ' "waterbuffalo" =~ /buff/ print $POSTMATCH, $PID, "\n"
Below is a full list of descriptive aliases and their associated global variable:
$!
$@
$;
$;
$,
$,
$/
$/
$\
$\
$.
$.
$_
$>
$<
$$
$$
$?
$~
$=
$*
$&
$‘
$‘
$+
The Find
module supports the top-down traversal of a set of file paths.
For example, to total the size of all files under your home directory, ignoring anything in a “dot” directory (e.g. $HOME/.ssh):
require 'find' total_size = 0 Find.find(ENV["HOME"]) do |path| if FileTest.directory?(path) if File.basename(path).start_with?('.') Find.prune # Don't look any further into this directory. else next end else total_size += FileTest.size(path) end end
URI
is a module providing classes to handle Uniform Resource Identifiers (RFC2396).
Uniform way of handling URIs.
Flexibility to introduce custom URI
schemes.
Flexibility to have an alternate URI::Parser
(or just different patterns and regexp’s).
require 'uri' uri = URI("http://foo.com/posts?id=30&limit=5#time=1305298413") #=> #<URI::HTTP http://foo.com/posts?id=30&limit=5#time=1305298413> uri.scheme #=> "http" uri.host #=> "foo.com" uri.path #=> "/posts" uri.query #=> "id=30&limit=5" uri.fragment #=> "time=1305298413" uri.to_s #=> "http://foo.com/posts?id=30&limit=5#time=1305298413"
module URI class RSYNC < Generic DEFAULT_PORT = 873 end register_scheme 'RSYNC', RSYNC end #=> URI::RSYNC URI.scheme_list #=> {"FILE"=>URI::File, "FTP"=>URI::FTP, "HTTP"=>URI::HTTP, # "HTTPS"=>URI::HTTPS, "LDAP"=>URI::LDAP, "LDAPS"=>URI::LDAPS, # "MAILTO"=>URI::MailTo, "RSYNC"=>URI::RSYNC} uri = URI("rsync://rsync.foo.com") #=> #<URI::RSYNC rsync://rsync.foo.com>
A good place to view an RFC spec is www.ietf.org/rfc.html.
Here is a list of all related RFC’s:
Class
tree URI::Generic
(in uri/generic.rb)
URI::File
- (in uri/file.rb)
URI::FTP
- (in uri/ftp.rb)
URI::HTTP
- (in uri/http.rb)
URI::HTTPS
- (in uri/https.rb)
URI::LDAP
- (in uri/ldap.rb)
URI::LDAPS
- (in uri/ldaps.rb)
URI::MailTo
- (in uri/mailto.rb)
URI::Parser
- (in uri/common.rb)
URI::REGEXP
- (in uri/common.rb)
URI::REGEXP::PATTERN - (in uri/common.rb)
URI::Util - (in uri/common.rb)
URI::Error
- (in uri/common.rb)
URI::InvalidURIError
- (in uri/common.rb)
URI::InvalidComponentError
- (in uri/common.rb)
URI::BadURIError
- (in uri/common.rb)
Akira Yamada <akira@ruby-lang.org>
Akira Yamada <akira@ruby-lang.org> Dmitry V. Sabanin <sdmitry@lrn.ru> Vincent Batts <vbatts@hashbangbash.com>
Copyright © 2001 akira yamada <akira@ruby-lang.org> You can redistribute it and/or modify it under the same term as Ruby.
OpenURI
is an easy-to-use wrapper for Net::HTTP
, Net::HTTPS and Net::FTP.
It is possible to open an http, https or ftp URL as though it were a file:
URI.open("http://www.ruby-lang.org/") {|f| f.each_line {|line| p line} }
The opened file has several getter methods for its meta-information, as follows, since it is extended by OpenURI::Meta
.
URI.open("http://www.ruby-lang.org/en") {|f| f.each_line {|line| p line} p f.base_uri # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/> p f.content_type # "text/html" p f.charset # "iso-8859-1" p f.content_encoding # [] p f.last_modified # Thu Dec 05 02:45:02 UTC 2002 }
Additional header fields can be specified by an optional hash argument.
URI.open("http://www.ruby-lang.org/en/", "User-Agent" => "Ruby/#{RUBY_VERSION}", "From" => "foo@bar.invalid", "Referer" => "http://www.ruby-lang.org/") {|f| # ... }
The environment variables such as http_proxy, https_proxy and ftp_proxy are in effect by default. Here we disable proxy:
URI.open("http://www.ruby-lang.org/en/", :proxy => nil) {|f| # ... }
See OpenURI::OpenRead.open
and URI.open
for more on available options.
URI
objects can be opened in a similar way.
uri = URI.parse("http://www.ruby-lang.org/en/") uri.open {|f| # ... }
URI
objects can be read directly. The returned string is also extended by OpenURI::Meta
.
str = uri.read p str.base_uri
Tanaka Akira <akr@m17n.org>
This is not an existing class, but documentation of the interface that Scheduler object should comply to in order to be used as argument to Fiber.scheduler
and handle non-blocking fibers. See also the “Non-blocking fibers” section in Fiber
class docs for explanations of some concepts.
Scheduler’s behavior and usage are expected to be as follows:
When the execution in the non-blocking Fiber
reaches some blocking operation (like sleep, wait for a process, or a non-ready I/O), it calls some of the scheduler’s hook methods, listed below.
Scheduler somehow registers what the current fiber is waiting on, and yields control to other fibers with Fiber.yield
(so the fiber would be suspended while expecting its wait to end, and other fibers in the same thread can perform)
At the end of the current thread execution, the scheduler’s method close
is called
The scheduler runs into a wait loop, checking all the blocked fibers (which it has registered on hook calls) and resuming them when the awaited resource is ready (e.g. I/O ready or sleep time elapsed).
A typical implementation would probably rely for this closing loop on a gem like EventMachine or Async.
This way concurrent execution will be achieved transparently for every individual Fiber’s code.
Hook methods are:
(the list is expanded as Ruby developers make more methods having non-blocking calls)
When not specified otherwise, the hook implementations are mandatory: if they are not implemented, the methods trying to call hook will fail. To provide backward compatibility, in the future hooks will be optional (if they are not implemented, due to the scheduler being created for the older Ruby version, the code which needs this hook will not fail, and will just behave in a blocking fashion).
It is also strongly recommended that the scheduler implements the fiber
method, which is delegated to by Fiber.schedule
.
Sample toy implementation of the scheduler can be found in Ruby’s code, in test/fiber/scheduler.rb
A base class for objects representing a C structure
Wrapper for arrays within a struct
A pointer to a C structure
This exception is raised if the required unicode support is missing on the system. Usually this means that the iconv library is not installed.
This class is the access to openssl’s ENGINE cryptographic module implementation.
See also, www.openssl.org/docs/crypto/engine.html
Psych::Stream
is a streaming YAML
emitter. It will not buffer your YAML
, but send it straight to an IO
.
Here is an example use:
stream = Psych::Stream.new($stdout) stream.start stream.push({:foo => 'bar'}) stream.finish
YAML
will be immediately emitted to $stdout with no buffering.
Psych::Stream#start
will take a block and ensure that Psych::Stream#finish
is called, so you can do this form:
stream = Psych::Stream.new($stdout) stream.start do |em| em.push(:foo => 'bar') end
Subclass of Zlib::Error
When zlib returns a Z_STREAM_END is return if the end of the compressed data has been reached and all uncompressed out put has been produced.
Subclass of Zlib::Error
When zlib returns a Z_STREAM_ERROR, usually if the stream state was inconsistent.
Zlib::ZStream
is the abstract class for the stream which handles the compressed data. The operations are defined in the subclasses: Zlib::Deflate
for compression, and Zlib::Inflate
for decompression.
An instance of Zlib::ZStream
has one stream (struct zstream in the source) and two variable-length buffers which associated to the input (next_in) of the stream and the output (next_out) of the stream. In this document, “input buffer” means the buffer for input, and “output buffer” means the buffer for output.
Data input into an instance of Zlib::ZStream
are temporally stored into the end of input buffer, and then data in input buffer are processed from the beginning of the buffer until no more output from the stream is produced (i.e. until avail_out
> 0 after processing). During processing, output buffer is allocated and expanded automatically to hold all output data.
Some particular instance methods consume the data in output buffer and return them as a String
.
Here is an ascii art for describing above:
+================ an instance of Zlib::ZStream ================+ || || || +--------+ +-------+ +--------+ || || +--| output |<---------|zstream|<---------| input |<--+ || || | | buffer | next_out+-------+next_in | buffer | | || || | +--------+ +--------+ | || || | | || +===|======================================================|===+ | | v | "output data" "input data"
If an error occurs during processing input buffer, an exception which is a subclass of Zlib::Error
is raised. At that time, both input and output buffer keep their conditions at the time when the error occurs.
Method
Catalogue Many of the methods in this class are fairly low-level and unlikely to be of interest to users. In fact, users are unlikely to use this class directly; rather they will be interested in Zlib::Inflate
and Zlib::Deflate
.
The higher level methods are listed below.