Potentially raised when a specification is validated.
Represents an error communicating via HTTP.
Raised by Resolver when a dependency requests a gem for which there is no spec.
Keyword completion module. This allows partial arguments to be specified and resolved against a list of acceptable values.
Mixin methods for local and remote Gem::Command
options.
An Encoding instance represents a character encoding usable in Ruby. It is defined as a constant under the Encoding namespace. It has a name and, optionally, aliases:
Encoding::US_ASCII.name # => "US-ASCII" Encoding::US_ASCII.names # => ["US-ASCII", "ASCII", "ANSI_X3.4-1968", "646"]
A Ruby method that accepts an encoding as an argument will accept:
An Encoding object.
The name of an encoding.
An alias for an encoding name.
These are equivalent:
'foo'.encode(Encoding::US_ASCII) # Encoding object. 'foo'.encode('US-ASCII') # Encoding name. 'foo'.encode('ASCII') # Encoding alias.
For a full discussion of encodings and their uses, see the Encodings document.
Encoding::ASCII_8BIT is a special-purpose encoding that is usually used for a string of bytes, not a string of characters. But as the name indicates, its characters in the ASCII range are considered as ASCII characters. This is useful when you use other ASCII-compatible encodings.
Raised when a feature is not implemented on the current platform. For example, methods depending on the fsync
or fork
system calls may raise this exception if the underlying operating system or Ruby runtime does not support them.
Note that if fork
raises a NotImplementedError
, then respond_to?(:fork)
returns false
.
EncodingError
is the base class for encoding errors.
Use the Monitor
class when you want to have a lock object for blocks with mutual exclusion.
require 'monitor' lock = Monitor.new lock.synchronize do # exclusive access end
In concurrent programming, a monitor is an object or module intended to be used safely by more than one thread. The defining characteristic of a monitor is that its methods are executed with mutual exclusion. That is, at each point in time, at most one thread may be executing any of its methods. This mutual exclusion greatly simplifies reasoning about the implementation of monitors compared to reasoning about parallel code that updates a data structure.
You can read more about the general principles on the Wikipedia page for Monitors.
require 'monitor.rb' buf = [] buf.extend(MonitorMixin) empty_cond = buf.new_cond # consumer Thread.start do loop do buf.synchronize do empty_cond.wait_while { buf.empty? } print buf.shift end end end # producer while line = ARGF.gets buf.synchronize do buf.push(line) empty_cond.signal end end
The consumer thread waits for the producer thread to push a line to buf while buf.empty?
. The producer thread (main thread) reads a line from ARGF
and pushes it into buf then calls empty_cond.signal
to notify the consumer thread of new data.
Class
include require 'monitor' class SynchronizedArray < Array include MonitorMixin def initialize(*args) super(*args) end alias :old_shift :shift alias :old_unshift :unshift def shift(n=1) self.synchronize do self.old_shift(n) end end def unshift(item) self.synchronize do self.old_unshift(item) end end # other methods ... end
SynchronizedArray
implements an Array
with synchronized access to items. This Class
is implemented as subclass of Array
which includes the MonitorMixin
module.
Namespace for file utility methods for copying, moving, removing, etc.
First, what’s elsewhere. Module FileUtils:
Inherits from class Object.
Supplements class File (but is not included or extended there).
Here, module FileUtils provides methods that are useful for:
::mkdir
: Creates directories.
::mkdir_p
, ::makedirs
, ::mkpath
: Creates directories, also creating ancestor directories as needed.
::link_entry
: Creates a hard link.
::ln_sf
: Creates symbolic links, overwriting if necessary.
::ln_sr
: Creates symbolic links relative to targets
::remove_dir
: Removes a directory and its descendants.
::remove_entry
: Removes an entry, including its descendants if it is a directory.
::remove_entry_secure
: Like ::remove_entry
, but removes securely.
::remove_file
: Removes a file entry.
::rm_f
, ::safe_unlink
: Like ::rm
, but removes forcibly.
::rm_r
: Removes entries and their descendants.
::rmdir
: Removes directories.
::uptodate?
: Returns whether a given entry is newer than given other entries.
::chmod
: Sets permissions for an entry.
::chmod_R
: Sets permissions for an entry and its descendants.
::chown
: Sets the owner and group for entries.
::chown_R
: Sets the owner and group for entries and their descendants.
::touch
: Sets modification and access times for entries, creating if necessary.
::compare_file
, ::cmp
, ::identical?
: Returns whether two entries are identical.
::compare_stream
: Returns whether two streams are identical.
::copy_entry
: Recursively copies an entry.
::copy_file
: Copies an entry.
::copy_stream
: Copies a stream.
::cp_lr
: Recursively creates hard links.
::cp_r
: Recursively copies files, retaining mode, owner, and group.
::install
: Recursively copies files, optionally setting mode, owner, and group.
::collect_method
: Returns the names of methods that accept a given option.
::commands
: Returns the names of methods that accept options.
::have_option?
: Returns whether a given method accepts a given option.
::options
: Returns all option names.
::options_of
: Returns the names of the options for a given method.
Some methods in FileUtils accept path arguments, which are interpreted as paths to filesystem entries:
If the argument is a string, that value is the path.
If the argument has method :to_path
, it is converted via that method.
If the argument has method :to_str
, it is converted via that method.
Some examples here involve trees of file entries. For these, we sometimes display trees using the tree command-line utility, which is a recursive directory-listing utility that produces a depth-indented listing of files and directories.
We use a helper method to launch the command and control the format:
def tree(dirpath = '.') command = "tree --noreport --charset=ascii #{dirpath}" system(command) end
To illustrate:
tree('src0') # => src0 # |-- sub0 # | |-- src0.txt # | `-- src1.txt # `-- sub1 # |-- src2.txt # `-- src3.txt
For certain methods that recursively remove entries, there is a potential vulnerability called the Time-of-check to time-of-use, or TOCTTOU, vulnerability that can exist when:
An ancestor directory of the entry at the target path is world writable; such directories include /tmp
.
The directory tree at the target path includes:
A world-writable descendant directory.
A symbolic link.
To avoid that vulnerability, you can use this method to remove entries:
FileUtils.remove_entry_secure
: removes recursively if the target path points to a directory.
Also available are these methods, each of which calls FileUtils.remove_entry_secure:
FileUtils.rm_r
with keyword argument secure: true
.
FileUtils.rm_rf
with keyword argument secure: true
.
Finally, this method for moving entries calls FileUtils.remove_entry_secure if the source and destination are on different file systems (which means that the “move” is really a copy and remove):
FileUtils.mv
with keyword argument secure: true
.
Method FileUtils.remove_entry_secure removes securely by applying a special pre-process:
If the target path points to a directory, this method uses methods File#chown
and File#chmod
in removing directories.
The owner of the target directory should be either the current process or the super user (root).
WARNING: You must ensure that ALL parent directories cannot be moved by other untrusted users. For example, parent directories should not be owned by untrusted users, and should not be world writable except when the sticky bit is set.
For details of this security vulnerability, see Perl cases:
The Singleton
module implements the Singleton
pattern.
To use Singleton
, include the module in your class.
class Klass include Singleton # ... end
This ensures that only one instance of Klass can be created.
a,b = Klass.instance, Klass.instance a == b # => true Klass.new # => NoMethodError - new is private ...
The instance is created at upon the first call of Klass.instance().
class OtherKlass include Singleton # ... end ObjectSpace.each_object(OtherKlass){} # => 0 OtherKlass.instance ObjectSpace.each_object(OtherKlass){} # => 1
This behavior is preserved under inheritance and cloning.
This above is achieved by:
Making Klass.new and Klass.allocate private.
Overriding Klass.inherited(sub_klass) and Klass.clone() to ensure that the Singleton
properties are kept when inherited and cloned.
Providing the Klass.instance() method that returns the same object each time it is called.
Overriding Klass._load(str) to call Klass.instance().
Overriding Klass#clone and Klass#dup to raise TypeErrors to prevent cloning or duping.
Singleton
and Marshal
By default Singleton’s _dump(depth)
returns the empty string. Marshalling by default will strip state information, e.g. instance variables from the instance. Classes using Singleton
can provide custom _load(str) and _dump(depth) methods to retain some of the previous state of the instance.
require 'singleton' class Example include Singleton attr_accessor :keep, :strip def _dump(depth) # this strips the @strip information from the instance Marshal.dump(@keep, depth) end def self._load(str) instance.keep = Marshal.load(str) instance end end a = Example.instance a.keep = "keep this" a.strip = "get rid of this" stored_state = Marshal.dump(a) a.keep = nil a.strip = nil b = Marshal.load(stored_state) p a == b # => true p a.keep # => "keep this" p a.strip # => nil
define UnicodeNormalize module here so that we don’t have to look it up
Response class for Unprocessable Entity
responses (status code 422).
The request was well-formed but had semantic errors.
References:
Represents the use of the ‘^` operator for pinning an expression in a pattern matching expression.
foo in ^(bar) ^^^^^^
Represents the use of the ‘until` keyword, either in the block form or the modifier form.
bar until foo ^^^^^^^^^^^^^ until foo do bar end ^^^^^^^^^^^^^^^^^^^^
Signals that a file permission error is preventing the user from operating on the given directory.
There are three main phases in the algorithm:
Sanitize/format input source
Search for invalid blocks
Format invalid blocks into something meaninful
The Code frontier is a critical part of the second step
## Knowing where we’ve been
Once a code block is generated it is added onto the frontier. Then it will be sorted by indentation and frontier can be filtered. Large blocks that fully enclose a smaller block will cause the smaller block to be evicted.
CodeFrontier#<<(block) # Adds block to frontier CodeFrontier#pop # Removes block from frontier
## Knowing where we can go
Internally the frontier keeps track of “unvisited” lines which are exposed via ‘next_indent_line` when called, this method returns, a line of code with the highest indentation.
The returned line of code can be used to build a CodeBlock
and then that code block is added back to the frontier. Then, the lines are removed from the “unvisited” so we don’t double-create the same block.
CodeFrontier#next_indent_line # Shows next line CodeFrontier#register_indent_block(block) # Removes lines from unvisited
## Knowing when to stop
The frontier knows how to check the entire document for a syntax error. When blocks are added onto the frontier, they’re removed from the document. When all code containing syntax errors has been added to the frontier, the document will be parsable without a syntax error and the search can stop.
CodeFrontier#holds_all_syntax_errors? # Returns true when frontier holds all syntax errors
## Filtering false positives
Once the search is completed, the frontier may have multiple blocks that do not contain the syntax error. To limit the result to the smallest subset of “invalid blocks” call:
CodeFrontier#detect_invalid_blocks
Mixin module providing HTML generation methods.
For example,
cgi.a("http://www.example.com") { "Example" } # => "<A HREF=\"http://www.example.com\">Example</A>"
Modules Html3, Html4, etc., contain more basic HTML-generation methods (#title
, #h1
, etc.).
See class CGI
for a detailed example.
Flags for regular expression and match last line nodes.
Enumerator::Product
generates a Cartesian product of any number of enumerable objects. Iterating over the product of enumerable objects is roughly equivalent to nested each_entry loops where the loop for the rightmost object is put innermost.
innings = Enumerator::Product.new(1..9, ['top', 'bottom']) innings.each do |i, h| p [i, h] end # [1, "top"] # [1, "bottom"] # [2, "top"] # [2, "bottom"] # [3, "top"] # [3, "bottom"] # ... # [9, "top"] # [9, "bottom"]
The method used against each enumerable object is ‘each_entry` instead of `each` so that the product of N enumerable objects yields an array of exactly N elements in each iteration.
When no enumerator is given, it calls a given block once yielding an empty argument list.
This type of objects can be created by Enumerator.product
.
Response class for Multiple Choices
responses (status code 300).
The Multiple Choices
response indicates that the server offers multiple options for the resource from which the client may choose.
References: