Raised by Gem::Validator
when something is not right in a gem.
Raised by Gem::WebauthnListener when an error occurs during security device verification.
This class is responsible for generating initial code blocks that will then later be expanded.
The biggest concern when guessing code blocks, is accidentally grabbing one that contains only an “end”. In this example:
def dog begonn # mispelled `begin` puts "bark" end end
The following lines would be matched (from bottom to top):
1) end 2) puts "bark" end 3) begonn puts "bark" end
At this point it has no where else to expand, and it will yield this inner code as a block
Not a URI
component.
Raised when a mathematical function is evaluated outside of its domain of definition.
For example, since cos
returns values in the range -1..1, its inverse function acos
is only defined on that interval:
Math.acos(42)
produces:
Math::DomainError: Numerical argument is out of domain - "acos"
Raised when an invalid operation is attempted on a Fiber
, in particular when attempting to call/resume a dead fiber, attempting to yield from the root fiber, or calling a fiber across threads.
fiber = Fiber.new{} fiber.resume #=> nil fiber.resume #=> FiberError: dead fiber called
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.
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 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 file required (a Ruby script, extension library, …) fails to load.
require 'this/file/does/not/exist'
raises the exception:
LoadError: no such file to load -- this/file/does/not/exist
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
No longer used by internal code.
Raised when memory allocation fails.