Parent class for server error (5xx) HTTP
response classes.
A server error response indicates that the server failed to fulfill a request.
References:
Raised by transcoding methods when a named encoding does not correspond with a known converter.
Numeric is the class from which all higher-level numeric classes should inherit.
Numeric allows instantiation of heap-allocated objects. Other core numeric classes such as Integer
are implemented as immediates, which means that each Integer
is a single immutable object which is always passed by value.
a = 1 1.object_id == a.object_id #=> true
There can only ever be one instance of the integer 1
, for example. Ruby ensures this by preventing instantiation. If duplication is attempted, the same instance is returned.
Integer.new(1) #=> NoMethodError: undefined method `new' for Integer:Class 1.dup #=> 1 1.object_id == 1.dup.object_id #=> true
For this reason, Numeric should be used when defining other numeric classes.
Classes which inherit from Numeric must implement coerce
, which returns a two-member Array
containing an object that has been coerced into an instance of the new class and self
(see coerce
).
Inheriting classes should also implement arithmetic operator methods (+
, -
, *
and /
) and the <=>
operator (see Comparable
). These methods may rely on coerce
to ensure interoperability with instances of other numeric classes.
class Tally < Numeric def initialize(string) @string = string end def to_s @string end def to_i @string.size end def coerce(other) [self.class.new('|' * other.to_i), self] end def <=>(other) to_i <=> other.to_i end def +(other) self.class.new('|' * (to_i + other.to_i)) end def -(other) self.class.new('|' * (to_i - other.to_i)) end def *(other) self.class.new('|' * (to_i * other.to_i)) end def /(other) self.class.new('|' * (to_i / other.to_i)) end end tally = Tally.new('||') puts tally * 2 #=> "||||" puts tally > 1 #=> true
First, what’s elsewhere. Class Numeric:
Inherits from class Object.
Includes module Comparable.
Here, class Numeric provides methods for:
finite?
: Returns true unless self
is infinite or not a number.
infinite?
: Returns -1, nil
or +1, depending on whether self
is -Infinity<tt>, finite, or <tt>+Infinity
.
integer?
: Returns whether self
is an integer.
negative?
: Returns whether self
is negative.
nonzero?
: Returns whether self
is not zero.
positive?
: Returns whether self
is positive.
real?
: Returns whether self
is a real value.
zero?
: Returns whether self
is zero.
<=>
: Returns:
-1 if self
is less than the given value.
0 if self
is equal to the given value.
1 if self
is greater than the given value.
nil
if self
and the given value are not comparable.
eql?
: Returns whether self
and the given value have the same value and type.
%
(aliased as modulo
): Returns the remainder of self
divided by the given value.
-@
: Returns the value of self
, negated.
abs
(aliased as magnitude
): Returns the absolute value of self
.
abs2
: Returns the square of self
.
angle
(aliased as arg
and phase
): Returns 0 if self
is positive, Math::PI otherwise.
ceil
: Returns the smallest number greater than or equal to self
, to a given precision.
coerce
: Returns array [coerced_self, coerced_other]
for the given other value.
conj
(aliased as conjugate
): Returns the complex conjugate of self
.
denominator
: Returns the denominator (always positive) of the Rational
representation of self
.
div
: Returns the value of self
divided by the given value and converted to an integer.
divmod
: Returns array [quotient, modulus]
resulting from dividing self
the given divisor.
fdiv
: Returns the Float
result of dividing self
by the given divisor.
floor
: Returns the largest number less than or equal to self
, to a given precision.
i
: Returns the Complex
object Complex(0, self)
. the given value.
imaginary
(aliased as imag
): Returns the imaginary part of the self
.
numerator
: Returns the numerator of the Rational
representation of self
; has the same sign as self
.
polar
: Returns the array [self.abs, self.arg]
.
quo
: Returns the value of self
divided by the given value.
real
: Returns the real part of self
.
rect
(aliased as rectangular
): Returns the array [self, 0]
.
remainder
: Returns self-arg*(self/arg).truncate
for the given arg
.
round
: Returns the value of self
rounded to the nearest value for the given a precision.
to_int
: Returns the Integer
representation of self
, truncating if necessary.
truncate
: Returns self
truncated (toward zero) to a given precision.
A Float object represents a sometimes-inexact real number using the native architecture’s double-precision floating point representation.
Floating point has a different arithmetic and is an inexact number. So you should know its esoteric system. See following:
You can create a Float object explicitly with:
A floating-point literal.
You can convert certain objects to Floats with:
Method Float
.
First, what’s elsewhere. Class Float:
Inherits from class Numeric and class Object.
Includes module Comparable.
Here, class Float provides methods for:
finite?
: Returns whether self
is finite.
hash
: Returns the integer hash code for self
.
infinite?
: Returns whether self
is infinite.
nan?
: Returns whether self
is a NaN (not-a-number).
<
: Returns whether self
is less than the given value.
<=
: Returns whether self
is less than or equal to the given value.
<=>
: Returns a number indicating whether self
is less than, equal to, or greater than the given value.
==
(aliased as ===
and eql?
): Returns whether self
is equal to the given value.
>
: Returns whether self
is greater than the given value.
>=
: Returns whether self
is greater than or equal to the given value.
*
: Returns the product of self
and the given value.
**
: Returns the value of self
raised to the power of the given value.
+
: Returns the sum of self
and the given value.
-
: Returns the difference of self
and the given value.
/
: Returns the quotient of self
and the given value.
ceil
: Returns the smallest number greater than or equal to self
.
coerce
: Returns a 2-element array containing the given value converted to a Float and self
divmod
: Returns a 2-element array containing the quotient and remainder results of dividing self
by the given value.
fdiv
: Returns the Float result of dividing self
by the given value.
floor
: Returns the greatest number smaller than or equal to self
.
next_float
: Returns the next-larger representable Float.
prev_float
: Returns the next-smaller representable Float.
quo
: Returns the quotient from dividing self
by the given value.
round
: Returns self
rounded to the nearest value, to a given precision.
to_i
(aliased as to_int
): Returns self
truncated to an Integer
.
to_s
(aliased as inspect
): Returns a string containing the place-value representation of self
in the given radix.
truncate
: Returns self
truncated to a given precision.
Fibers are primitives for implementing light weight cooperative concurrency in Ruby. Basically they are a means of creating code blocks that can be paused and resumed, much like threads. The main difference is that they are never preempted and that the scheduling must be done by the programmer and not the VM.
As opposed to other stackless light weight concurrency models, each fiber comes with a stack. This enables the fiber to be paused from deeply nested function calls within the fiber block. See the ruby(1) manpage to configure the size of the fiber stack(s).
When a fiber is created it will not run automatically. Rather it must be explicitly asked to run using the Fiber#resume
method. The code running inside the fiber can give up control by calling Fiber.yield
in which case it yields control back to caller (the caller of the Fiber#resume
).
Upon yielding or termination the Fiber
returns the value of the last executed expression
For instance:
fiber = Fiber.new do Fiber.yield 1 2 end puts fiber.resume puts fiber.resume puts fiber.resume
produces
1 2 FiberError: dead fiber called
The Fiber#resume
method accepts an arbitrary number of parameters, if it is the first call to resume
then they will be passed as block arguments. Otherwise they will be the return value of the call to Fiber.yield
Example:
fiber = Fiber.new do |first| second = Fiber.yield first + 2 end puts fiber.resume 10 puts fiber.resume 1_000_000 puts fiber.resume "The fiber will be dead before I can cause trouble"
produces
12 1000000 FiberError: dead fiber called
The concept of non-blocking fiber was introduced in Ruby 3.0. A non-blocking fiber, when reaching a operation that would normally block the fiber (like sleep
, or wait for another process or I/O) will yield control to other fibers and allow the scheduler to handle blocking and waking up (resuming) this fiber when it can proceed.
For a Fiber
to behave as non-blocking, it need to be created in Fiber.new
with blocking: false
(which is the default), and Fiber.scheduler
should be set with Fiber.set_scheduler
. If Fiber.scheduler
is not set in the current thread, blocking and non-blocking fibers’ behavior is identical.
Ruby doesn’t provide a scheduler class: it is expected to be implemented by the user and correspond to Fiber::Scheduler
.
There is also Fiber.schedule
method, which is expected to immediately perform the given block in a non-blocking manner. Its actual implementation is up to the scheduler.
A class which allows both internal and external iteration.
An Enumerator
can be created by the following methods.
Most methods have two forms: a block form where the contents are evaluated for each item in the enumeration, and a non-block form which returns a new Enumerator
wrapping the iteration.
enumerator = %w(one two three).each puts enumerator.class # => Enumerator enumerator.each_with_object("foo") do |item, obj| puts "#{obj}: #{item}" end # foo: one # foo: two # foo: three enum_with_obj = enumerator.each_with_object("foo") puts enum_with_obj.class # => Enumerator enum_with_obj.each do |item, obj| puts "#{obj}: #{item}" end # foo: one # foo: two # foo: three
This allows you to chain Enumerators together. For example, you can map a list’s elements to strings containing the index and the element as a string via:
puts %w[foo bar baz].map.with_index { |w, i| "#{i}:#{w}" } # => ["0:foo", "1:bar", "2:baz"]
An Enumerator
can also be used as an external iterator. For example, Enumerator#next
returns the next value of the iterator or raises StopIteration
if the Enumerator
is at the end.
e = [1,2,3].each # returns an enumerator object. puts e.next # => 1 puts e.next # => 2 puts e.next # => 3 puts e.next # raises StopIteration
next
, next_values
, peek
, and peek_values
are the only methods which use external iteration (and Array#zip(Enumerable-not-Array)
which uses next
internally).
These methods do not affect other internal enumeration methods, unless the underlying iteration method itself has side-effect, e.g. IO#each_line
.
FrozenError
will be raised if these methods are called against a frozen enumerator. Since rewind
and feed
also change state for external iteration, these methods may raise FrozenError
too.
External iteration differs significantly from internal iteration due to using a Fiber:
The Fiber
adds some overhead compared to internal enumeration.
The stacktrace will only include the stack from the Enumerator
, not above.
Fiber-local variables are not inherited inside the Enumerator
Fiber
, which instead starts with no Fiber-local variables.
Fiber
storage variables are inherited and are designed to handle Enumerator
Fibers. Assigning to a Fiber
storage variable only affects the current Fiber
, so if you want to change state in the caller Fiber
of the Enumerator
Fiber
, you need to use an extra indirection (e.g., use some object in the Fiber
storage variable and mutate some ivar of it).
Concretely:
Thread.current[:fiber_local] = 1 Fiber[:storage_var] = 1 e = Enumerator.new do |y| p Thread.current[:fiber_local] # for external iteration: nil, for internal iteration: 1 p Fiber[:storage_var] # => 1, inherited Fiber[:storage_var] += 1 y << 42 end p e.next # => 42 p Fiber[:storage_var] # => 1 (it ran in a different Fiber) e.each { p _1 } p Fiber[:storage_var] # => 2 (it ran in the same Fiber/"stack" as the current Fiber)
You can use an external iterator to implement an internal iterator as follows:
def ext_each(e) while true begin vs = e.next_values rescue StopIteration return $!.result end y = yield(*vs) e.feed y end end o = Object.new def o.each puts yield puts yield(1) puts yield(1, 2) 3 end # use o.each as an internal iterator directly. puts o.each {|*x| puts x; [:b, *x] } # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3 # convert o.each to an external iterator for # implementing an internal iterator. puts ext_each(o.to_enum) {|*x| puts x; [:b, *x] } # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
Raised to stop the iteration, in particular by Enumerator#next
. It is rescued by Kernel#loop
.
loop do puts "Hello" raise StopIteration puts "World" end puts "Done!"
produces:
Hello Done!
Raised when the interrupt signal is received, typically because the user has pressed Control-C (on most posix platforms). As such, it is a subclass of SignalException
.
begin puts "Press ctrl-C when you get bored" loop {} rescue Interrupt => e puts "Note: You will typically use Signal.trap instead." end
produces:
Press ctrl-C when you get bored
then waits until it is interrupted with Control-C and then prints:
Note: You will typically use Signal.trap instead.
The most standard error types are subclasses of StandardError
. A rescue clause without an explicit Exception
class will rescue all StandardErrors (and only those).
def foo raise "Oups" end foo rescue "Hello" #=> "Hello"
On the other hand:
require 'does/not/exist' rescue "Hi"
raises the exception:
LoadError: no such file to load -- does/not/exist
Raised when encountering an object that is not of the expected type.
[1, 2, 3].first("two")
raises the exception:
TypeError: no implicit conversion of String into Integer
Raised when the arguments are wrong and there isn’t a more specific Exception
class.
Ex: passing the wrong number of arguments
[1, 2, 3].first(4, 5)
raises the exception:
ArgumentError: wrong number of arguments (given 2, expected 1)
Ex: passing an argument that is not acceptable:
[1, 2, 3].first(-4)
raises the exception:
ArgumentError: negative array size
Raised when the given index is invalid.
a = [:foo, :bar] a.fetch(0) #=> :foo a[4] #=> nil a.fetch(4) #=> IndexError: index 4 outside of array bounds: -2...2
Raised when the specified key is not found. It is a subclass of IndexError
.
h = {"foo" => :bar} h.fetch("foo") #=> :bar h.fetch("baz") #=> KeyError: key not found: "baz"
ScriptError
is the superclass for errors raised when a script can not be executed because of a LoadError
, NotImplementedError
or a SyntaxError
. Note these type of ScriptErrors
are not StandardError
and will not be rescued unless it is specified explicitly (or its ancestor Exception
).
Raised when encountering Ruby code with an invalid syntax.
eval("1+1=2")
raises the exception:
SyntaxError: (eval):1: syntax error, unexpected '=', expecting $end
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
.
Raised when a given name is invalid or undefined.
puts foo
raises the exception:
NameError: undefined local variable or method `foo' for main:Object
Since constant names must start with a capital:
Integer.const_set :answer, 42
raises the exception:
NameError: wrong constant name answer
Raised when a method is called on a receiver which doesn’t have it defined and also fails to respond with method_missing
.
"hello".to_ary
raises the exception:
NoMethodError: undefined method `to_ary' for an instance of String
A generic error class raised when an invalid operation is attempted. Kernel#raise
will raise a RuntimeError
if no Exception
class is specified.
raise "ouch"
raises the exception:
RuntimeError: ouch
Raised when there is an attempt to modify a frozen object.
[1, 2, 3].freeze << 4
raises the exception:
FrozenError: can't modify frozen Array
No longer used by internal code.