Response class for Switching Protocol
responses (status code 101).
The <tt>Switching Protocol<tt> response indicates that the server has received a request to switch protocols, and has agreed to do so.
References:
Raised by exit
to initiate the termination of the script.
Raised when encountering Ruby code with an invalid syntax.
eval("1+1=2")
raises the exception:
SyntaxError: (eval):1: syntax error, unexpected '=', expecting $end
SystemCallError
is the base class for all low-level platform-dependent errors.
The errors available on the current platform are subclasses of SystemCallError
and are defined in the Errno
module.
File.open("does/not/exist")
raises the exception:
Errno::ENOENT: No such file or directory - does/not/exist
Symbol objects represent named identifiers inside the Ruby interpreter.
You can create a Symbol object explicitly with:
A symbol literal.
The same Symbol object will be created for a given name or string for the duration of a program’s execution, regardless of the context or meaning of that name. Thus if Fred
is a constant in one context, a method in another, and a class in a third, the Symbol :Fred
will be the same object in all three contexts.
module One class Fred end $f1 = :Fred end module Two Fred = 1 $f2 = :Fred end def Fred() end $f3 = :Fred $f1.object_id #=> 2514190 $f2.object_id #=> 2514190 $f3.object_id #=> 2514190
Constant, method, and variable names are returned as symbols:
module One Two = 2 def three; 3 end @four = 4 @@five = 5 $six = 6 end seven = 7 One.constants # => [:Two] One.instance_methods(true) # => [:three] One.instance_variables # => [:@four] One.class_variables # => [:@@five] global_variables.grep(/six/) # => [:$six] local_variables # => [:seven]
Symbol objects are different from String
objects in that Symbol objects represent identifiers, while String
objects represent text or data.
First, what’s elsewhere. Class Symbol:
Inherits from class Object.
Includes module Comparable.
Here, class Symbol provides methods that are useful for:
::all_symbols
: Returns an array of the symbols currently in Ruby’s symbol table.
=~
: Returns the index of the first substring in symbol that matches a given Regexp
or other object; returns nil
if no match is found.
[]
, slice
: Returns a substring of symbol determined by a given index, start/length, or range, or string.
empty?
: Returns true
if self.length
is zero; false
otherwise.
encoding
: Returns the Encoding
object that represents the encoding of symbol.
end_with?
: Returns true
if symbol ends with any of the given strings.
match
: Returns a MatchData
object if symbol matches a given Regexp
; nil
otherwise.
match?
: Returns true
if symbol matches a given Regexp
; false
otherwise.
start_with?
: Returns true
if symbol starts with any of the given strings.
<=>
: Returns -1, 0, or 1 as a given symbol is smaller than, equal to, or larger than symbol.
==
, ===
: Returns true
if a given symbol has the same content and encoding.
casecmp
: Ignoring case, returns -1, 0, or 1 as a given symbol is smaller than, equal to, or larger than symbol.
casecmp?
: Returns true
if symbol is equal to a given symbol after Unicode case folding; false
otherwise.
capitalize
: Returns symbol with the first character upcased and all other characters downcased.
downcase
: Returns symbol with all characters downcased.
inspect
: Returns the string representation of self
as a symbol literal.
name
: Returns the frozen string corresponding to symbol.
succ
, next
: Returns the symbol that is the successor to symbol.
swapcase
: Returns symbol with all upcase characters downcased and all downcase characters upcased.
to_proc
: Returns a Proc
object which responds to the method named by symbol.
upcase
: Returns symbol with all characters upcased.
TCPServer
represents a TCP/IP server socket.
A simple TCP server may look like:
require 'socket' server = TCPServer.new 2000 # Server bind to port 2000 loop do client = server.accept # Wait for a client to connect client.puts "Hello !" client.puts "Time is #{Time.now}" client.close end
A more usable server (serving multiple clients):
require 'socket' server = TCPServer.new 2000 loop do Thread.start(server.accept) do |client| client.puts "Hello !" client.puts "Time is #{Time.now}" client.close end end
TCPSocket
represents a TCP/IP client socket.
A simple client may look like:
require 'socket' s = TCPSocket.new 'localhost', 2000 while line = s.gets # Read lines from socket puts line # and print them end s.close # close socket when done
MatchData
encapsulates the result of matching a Regexp
against string. It is returned by Regexp#match
and String#match
, and also stored in a global variable returned by Regexp.last_match
.
Usage:
url = 'https://docs.ruby-lang.org/en/2.5.0/MatchData.html' m = url.match(/(\d\.?)+/) # => #<MatchData "2.5.0" 1:"0"> m.string # => "https://docs.ruby-lang.org/en/2.5.0/MatchData.html" m.regexp # => /(\d\.?)+/ # entire matched substring: m[0] # => "2.5.0" # Working with unnamed captures m = url.match(%r{([^/]+)/([^/]+)\.html$}) m.captures # => ["2.5.0", "MatchData"] m[1] # => "2.5.0" m.values_at(1, 2) # => ["2.5.0", "MatchData"] # Working with named captures m = url.match(%r{(?<version>[^/]+)/(?<module>[^/]+)\.html$}) m.captures # => ["2.5.0", "MatchData"] m.named_captures # => {"version"=>"2.5.0", "module"=>"MatchData"} m[:version] # => "2.5.0" m.values_at(:version, :module) # => ["2.5.0", "MatchData"] # Numerical indexes are working, too m[1] # => "2.5.0" m.values_at(1, 2) # => ["2.5.0", "MatchData"]
Parts of last MatchData
(returned by Regexp.last_match
) are also aliased as global variables:
$~
is Regexp.last_match
;
$&
is Regexp.last_match
[ 0 ]
;
$1
, $2
, and so on are Regexp.last_match
[ i ]
(captures by number);
$`
is Regexp.last_match
.pre_match
;
$'
is Regexp.last_match
.post_match
;
$+
is Regexp.last_match
[ -1 ]
(the last capture).
See also “Special global variables” section in Regexp
documentation.
PStore implements a file based persistence mechanism based on a Hash
. User code can store hierarchies of Ruby objects (values) into the data store 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.
There are three important concepts here (details at the links):
Store: a store is an instance of PStore.
Entries: the store is hash-like; each entry is the key for a stored object.
Transactions: each transaction is a collection of prospective changes to the store; a transaction is defined in the block given with a call to PStore#transaction
.
Examples on this page need a store that has known properties. They can get a new (and populated) store by calling thus:
example_store do |store| # Example code using store goes here. end
All we really need to know about example_store
is that it yields a fresh store with a known population of entries; its implementation:
require 'pstore' require 'tempfile' # Yield a pristine store for use in examples. def example_store # Create the store in a temporary file. Tempfile.create do |file| store = PStore.new(file) # Populate the store. store.transaction do store[:foo] = 0 store[:bar] = 1 store[:baz] = 2 end yield store end end
The contents of the store are maintained in a file whose path is specified when the store is created (see PStore.new
). The objects are stored and retrieved using module Marshal
, which means that certain objects cannot be added to the store; see Marshal::dump.
A store may have any number of entries. Each entry 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 Keys. You may find it convenient to keep it simple by using only symbols or strings as keys.
Value: the value may be any object that can be marshalled by Marshal (see Marshal::dump) and in fact may be a collection (e.g., an array, a hash, a set, a range, etc). That collection may in turn contain nested objects, including collections, to any depth; those objects must also be Marshal-able. See Hierarchical Values.
The block given with a call to method transaction
# contains a transaction, which consists of calls to PStore methods that read from or write to the store (that is, all PStore methods except transaction
itself, path
, and Pstore.new):
example_store do |store| store.transaction do store.keys # => [:foo, :bar, :baz] store[:bat] = 3 store.keys # => [:foo, :bar, :baz, :bat] end end
Execution of the transaction is deferred until the block exits, and is executed atomically (all-or-nothing): either all transaction calls are executed, or none are. This maintains the integrity of the store.
Other code in the block (including even calls to path
and PStore.new
) is executed immediately, not deferred.
The transaction block:
May not contain a nested call to transaction
.
Is the only context where methods that read from or write to the store are allowed.
As seen above, changes in a transaction are made automatically when the block exits. The block may be exited early by calling method commit
or abort
.
Method
commit
triggers the update to the store and exits the block:
example_store do |store| store.transaction do store.keys # => [:foo, :bar, :baz] store[:bat] = 3 store.commit fail 'Cannot get here' end store.transaction do # Update was completed. store.keys # => [:foo, :bar, :baz, :bat] end end
Method
abort
discards the update to the store and exits the block:
example_store do |store| store.transaction do store.keys # => [:foo, :bar, :baz] store[:bat] = 3 store.abort fail 'Cannot get here' end store.transaction do # Update was not completed. store.keys # => [:foo, :bar, :baz] end end
By default, a transaction allows both reading from and writing to the store:
store.transaction do # Read-write transaction. # Any code except a call to #transaction is allowed here. end
If argument read_only
is passed as true
, only reading is allowed:
store.transaction(true) do # Read-only transaction: # Calls to #transaction, #[]=, and #delete are not allowed here. end
The value for an entry 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 in a returned hierarchy of objects.
Use method PStore.new
to create a store. The new store creates or opens its containing file:
store = PStore.new('t.store')
Use method []=
to update or create an entry:
example_store do |store| store.transaction do store[:foo] = 1 # Update. store[:bam] = 1 # Create. end end
Use method delete
to remove an entry:
example_store do |store| store.transaction do store.delete(:foo) store[:foo] # => nil end end
Use method fetch
(allows default) or []
(defaults to nil
) to retrieve an entry:
example_store do |store| store.transaction do store[:foo] # => 0 store[:nope] # => nil store.fetch(:baz) # => 2 store.fetch(:nope, nil) # => nil store.fetch(:nope) # Raises exception. end end
Use method key?
to determine whether a given key exists:
example_store do |store| store.transaction do store.key?(:foo) # => true end end
Use method keys
to retrieve keys:
example_store do |store| store.transaction do store.keys # => [:foo, :bar, :baz] end end
Use method path
to retrieve the path to the store’s underlying file; this method may be called from outside a transaction block:
store = PStore.new('t.store') store.path # => "t.store"
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.
require "pstore" # A mock wiki object. class WikiPage attr_reader :page_name def initialize(page_name, author, contents) @page_name = page_name @revisions = Array.new add_revision(author, contents) end 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 wiki page. home_page = WikiPage.new("HomePage", "James Edward Gray II", "A page about the JoysOfDocumentation..." ) wiki = PStore.new("wiki_pages.pstore") # Update page data and the index together, or not at all. wiki.transaction do # Store page. wiki[home_page.page_name] = home_page # Create page index. wiki[:wiki_index] ||= Array.new # Update wiki index. wiki[:wiki_index].push(*home_page.wiki_page_references) end # Read wiki data, setting argument read_only to true. wiki.transaction(true) do wiki.keys.each do |key| puts key puts wiki[key] end end
Raised in case of a stack overflow.
def me_myself_and_i me_myself_and_i end me_myself_and_i
raises the exception:
SystemStackError: stack level too deep
The syslog package provides a Ruby interface to the POSIX system logging facility.
Syslog
messages are typically passed to a central logging daemon. The daemon may filter them; route them into different files (usually found under /var/log); place them in SQL databases; forward them to centralized logging servers via TCP or UDP; or even alert the system administrator via email, pager or text message.
Unlike application-level logging via Logger
or Log4r, syslog is designed to allow secure tamper-proof logging.
The syslog protocol is standardized in RFC 5424.
The Benchmark
module provides methods to measure and report the time used to execute Ruby code.
Measure the time to construct the string given by the expression "a"*1_000_000_000
:
require 'benchmark' puts Benchmark.measure { "a"*1_000_000_000 }
On my machine (OSX 10.8.3 on i5 1.7 GHz) this generates:
0.350000 0.400000 0.750000 ( 0.835234)
This report shows the user CPU time, system CPU time, the sum of the user and system CPU times, and the elapsed real time. The unit of time is seconds.
Do some experiments sequentially using the bm
method:
require 'benchmark' n = 5000000 Benchmark.bm do |x| x.report { for i in 1..n; a = "1"; end } x.report { n.times do ; a = "1"; end } x.report { 1.upto(n) do ; a = "1"; end } end
The result:
user system total real 1.010000 0.000000 1.010000 ( 1.014479) 1.000000 0.000000 1.000000 ( 0.998261) 0.980000 0.000000 0.980000 ( 0.981335)
Continuing the previous example, put a label in each report:
require 'benchmark' n = 5000000 Benchmark.bm(7) do |x| x.report("for:") { for i in 1..n; a = "1"; end } x.report("times:") { n.times do ; a = "1"; end } x.report("upto:") { 1.upto(n) do ; a = "1"; end } end
The result:
user system total real for: 1.010000 0.000000 1.010000 ( 1.015688) times: 1.000000 0.000000 1.000000 ( 1.003611) upto: 1.030000 0.000000 1.030000 ( 1.028098)
The times for some benchmarks depend on the order in which items are run. These differences are due to the cost of memory allocation and garbage collection. To avoid these discrepancies, the bmbm
method is provided. For example, to compare ways to sort an array of floats:
require 'benchmark' array = (1..1000000).map { rand } Benchmark.bmbm do |x| x.report("sort!") { array.dup.sort! } x.report("sort") { array.dup.sort } end
The result:
Rehearsal ----------------------------------------- sort! 1.490000 0.010000 1.500000 ( 1.490520) sort 1.460000 0.000000 1.460000 ( 1.463025) -------------------------------- total: 2.960000sec user system total real sort! 1.460000 0.000000 1.460000 ( 1.460465) sort 1.450000 0.010000 1.460000 ( 1.448327)
Report statistics of sequential experiments with unique labels, using the benchmark
method:
require 'benchmark' include Benchmark # we need the CAPTION and FORMAT constants n = 5000000 Benchmark.benchmark(CAPTION, 7, FORMAT, ">total:", ">avg:") do |x| tf = x.report("for:") { for i in 1..n; a = "1"; end } tt = x.report("times:") { n.times do ; a = "1"; end } tu = x.report("upto:") { 1.upto(n) do ; a = "1"; end } [tf+tt+tu, (tf+tt+tu)/3] end
The result:
user system total real for: 0.950000 0.000000 0.950000 ( 0.952039) times: 0.980000 0.000000 0.980000 ( 0.984938) upto: 0.950000 0.000000 0.950000 ( 0.946787) >total: 2.880000 0.000000 2.880000 ( 2.883764) >avg: 0.960000 0.000000 0.960000 ( 0.961255)
Emit a scalar with value
and tag
Emit a sequence with list
and tag
Emit a sequence with map
and tag
Emit an arbitrary object obj
and tag
Called with encoding
when the YAML
stream starts. This method is called once per stream. A stream may contain multiple documents.
See the constants in Psych::Parser
for the possible values of encoding
.
Called when the document starts with the declared version
, tag_directives
, if the document is implicit
.
version
will be an array of integers indicating the YAML
version being dealt with, tag_directives
is a list of tuples indicating the prefix and suffix of each tag, and implicit
is a boolean indicating whether the document is started implicitly.
Given the following YAML:
%YAML 1.1 %TAG ! tag:tenderlovemaking.com,2009: --- !squee
The parameters for start_document
must be this:
version # => [1, 1] tag_directives # => [["!", "tag:tenderlovemaking.com,2009:"]] implicit # => false
Called with the document ends. implicit
is a boolean value indicating whether or not the document has an implicit ending.
Given the following YAML:
--- hello world
implicit
will be true. Given this YAML:
--- hello world ...
implicit
will be false.
Called when a sequence is started.
anchor
is the anchor associated with the sequence or nil. tag
is the tag associated with the sequence or nil. implicit
a boolean indicating whether or not the sequence was implicitly started. style
is an integer indicating the list style.
See the constants in Psych::Nodes::Sequence
for the possible values of style
.
Here is a YAML
document that exercises most of the possible ways this method can be called:
--- - !!seq [ a ] - &pewpew - b
The above YAML
document consists of three lists, an outer list that contains two inner lists. Here is a matrix of the parameters sent to represent these lists:
# anchor tag implicit style [nil, nil, true, 1 ] [nil, "tag:yaml.org,2002:seq", false, 2 ] ["pewpew", nil, true, 1 ]