ThreadGroup
provides a means of keeping track of a number of threads as a group.
A given Thread
object can only belong to one ThreadGroup
at a time; adding a thread to a new group will remove it from any previous group.
Newly created threads belong to the same group as the thread from which they were created.
Raised when an invalid operation is attempted on a thread.
For example, when no other thread has been started:
Thread.stop
This will raises the following exception:
ThreadError: stopping only thread note: use sleep to stop forever
Threads are the Ruby implementation for a concurrent programming model.
Programs that require multiple threads of execution are a perfect candidate for Ruby’s Thread
class.
For example, we can create a new thread separate from the main thread’s execution using ::new
.
thr = Thread.new { puts "What's the big deal" }
Then we are able to pause the execution of the main thread and allow our new thread to finish, using join
:
thr.join #=> "What's the big deal"
If we don’t call thr.join
before the main thread terminates, then all other threads including thr
will be killed.
Alternatively, you can use an array for handling multiple threads at once, like in the following example:
threads = [] threads << Thread.new { puts "What's the big deal" } threads << Thread.new { 3.times { puts "Threads are fun!" } }
After creating a few threads we wait for them all to finish consecutively.
threads.each { |thr| thr.join }
To retrieve the last value of a thread, use value
thr = Thread.new { sleep 1; "Useful value" } thr.value #=> "Useful value"
Thread
initialization In order to create new threads, Ruby provides ::new
, ::start
, and ::fork
. A block must be provided with each of these methods, otherwise a ThreadError
will be raised.
When subclassing the Thread
class, the initialize
method of your subclass will be ignored by ::start
and ::fork
. Otherwise, be sure to call super in your initialize
method.
Thread
termination For terminating threads, Ruby provides a variety of ways to do this.
The class method ::kill
, is meant to exit a given thread:
thr = Thread.new { sleep } Thread.kill(thr) # sends exit() to thr
Alternatively, you can use the instance method exit
, or any of its aliases kill
or terminate
.
thr.exit
Thread
status Ruby provides a few instance methods for querying the state of a given thread. To get a string with the current thread’s state use status
thr = Thread.new { sleep } thr.status # => "sleep" thr.exit thr.status # => false
You can also use alive?
to tell if the thread is running or sleeping, and stop?
if the thread is dead or sleeping.
Thread
variables and scope Since threads are created with blocks, the same rules apply to other Ruby blocks for variable scope. Any local variables created within this block are accessible to only this thread.
Each fiber has its own bucket for Thread#[]
storage. When you set a new fiber-local it is only accessible within this Fiber
. To illustrate:
Thread.new { Thread.current[:foo] = "bar" Fiber.new { p Thread.current[:foo] # => nil }.resume }.join
This example uses []
for getting and []=
for setting fiber-locals, you can also use keys
to list the fiber-locals for a given thread and key?
to check if a fiber-local exists.
When it comes to thread-locals, they are accessible within the entire scope of the thread. Given the following example:
Thread.new{ Thread.current.thread_variable_set(:foo, 1) p Thread.current.thread_variable_get(:foo) # => 1 Fiber.new{ Thread.current.thread_variable_set(:foo, 2) p Thread.current.thread_variable_get(:foo) # => 2 }.resume p Thread.current.thread_variable_get(:foo) # => 2 }.join
You can see that the thread-local :foo
carried over into the fiber and was changed to 2
by the end of the thread.
This example makes use of thread_variable_set
to create new thread-locals, and thread_variable_get
to reference them.
There is also thread_variables
to list all thread-locals, and thread_variable?
to check if a given thread-local exists.
Exception
handling When an unhandled exception is raised inside a thread, it will terminate. By default, this exception will not propagate to other threads. The exception is stored and when another thread calls value
or join
, the exception will be re-raised in that thread.
t = Thread.new{ raise 'something went wrong' } t.value #=> RuntimeError: something went wrong
An exception can be raised from outside the thread using the Thread#raise
instance method, which takes the same parameters as Kernel#raise
.
Setting Thread.abort_on_exception
= true, Thread#abort_on_exception
= true, or $DEBUG = true will cause a subsequent unhandled exception raised in a thread to be automatically re-raised in the main thread.
With the addition of the class method ::handle_interrupt
, you can now handle exceptions asynchronously with threads.
Ruby provides a few ways to support scheduling threads in your program.
The first way is by using the class method ::stop
, to put the current running thread to sleep and schedule the execution of another thread.
Once a thread is asleep, you can use the instance method wakeup
to mark your thread as eligible for scheduling.
You can also try ::pass
, which attempts to pass execution to another thread but is dependent on the OS whether a running thread will switch or not. The same goes for priority
, which lets you hint to the thread scheduler which threads you want to take precedence when passing execution. This method is also dependent on the OS and may be ignored on some platforms.
Raised when throw
is called with a tag which does not have corresponding catch
block.
throw "foo", "bar"
raises the exception:
UncaughtThrowError: uncaught throw "foo"
The Comparable
mixin is used by classes whose objects may be ordered. The class must define the <=>
operator, which compares the receiver against another object, returning a value less than 0, returning 0, or returning a value greater than 0, depending on whether the receiver is less than, equal to, or greater than the other object. If the other object is not comparable then the <=>
operator should return nil
. Comparable
uses <=>
to implement the conventional comparison operators (<
, <=
, ==
, >=
, and >
) and the method between?
.
class StringSorter include Comparable attr :str def <=>(other) str.size <=> other.str.size end def initialize(str) @str = str end def inspect @str end end s1 = StringSorter.new("Z") s2 = StringSorter.new("YY") s3 = StringSorter.new("XXX") s4 = StringSorter.new("WWWW") s5 = StringSorter.new("VVVVV") s1 < s2 #=> true s4.between?(s1, s3) #=> false s4.between?(s3, s5) #=> true [ s3, s2, s5, s4, s1 ].sort #=> [Z, YY, XXX, WWWW, VVVVV]
Module Comparable provides these methods, all of which use method <=>
:
<
: Returns whether self
is less than the given object.
<=
: Returns whether self
is less than or equal to the given object.
==
: Returns whether self
is equal to the given object.
>
: Returns whether self
is greater than the given object.
>=
: Returns whether self
is greater than or equal to the given object.
between?
: Returns true
if self
is between two given objects.
clamp
: For given objects min
and max
, or range (min..max)
, returns:
min
if (self <=> min) < 0
.
max
if (self <=> max) > 0
.
self
otherwise.
Module Enumerable provides methods that are useful to a collection class for:
These methods return information about the Enumerable other than the elements themselves:
include?
, member?
: Returns true
if self == object
, false
otherwise.
all?
: Returns true
if all elements meet a specified criterion; false
otherwise.
any?
: Returns true
if any element meets a specified criterion; false
otherwise.
none?
: Returns true
if no element meets a specified criterion; false
otherwise.
one?
: Returns true
if exactly one element meets a specified criterion; false
otherwise.
count
: Returns the count of elements, based on an argument or block criterion, if given.
tally
: Returns a new Hash
containing the counts of occurrences of each element.
These methods return entries from the Enumerable, without modifying it:
Leading, trailing, or all elements:
first
: Returns the first element or leading elements.
take
: Returns a specified number of leading elements.
drop
: Returns a specified number of trailing elements.
take_while
: Returns leading elements as specified by the given block.
drop_while
: Returns trailing elements as specified by the given block.
Minimum and maximum value elements:
min
: Returns the elements whose values are smallest among the elements, as determined by <=>
or a given block.
max
: Returns the elements whose values are largest among the elements, as determined by <=>
or a given block.
minmax
: Returns a 2-element Array
containing the smallest and largest elements.
min_by
: Returns the smallest element, as determined by the given block.
max_by
: Returns the largest element, as determined by the given block.
minmax_by
: Returns the smallest and largest elements, as determined by the given block.
Groups, slices, and partitions:
group_by
: Returns a Hash
that partitions the elements into groups.
partition
: Returns elements partitioned into two new Arrays, as determined by the given block.
slice_after
: Returns a new Enumerator
whose entries are a partition of self
, based either on a given object
or a given block.
slice_before
: Returns a new Enumerator
whose entries are a partition of self
, based either on a given object
or a given block.
slice_when
: Returns a new Enumerator
whose entries are a partition of self
based on the given block.
chunk
: Returns elements organized into chunks as specified by the given block.
chunk_while
: Returns elements organized into chunks as specified by the given block.
These methods return elements that meet a specified criterion:
find_all
, filter
, select
: Returns elements selected by the block.
find_index
: Returns the index of an element selected by a given object or block.
reject
: Returns elements not rejected by the block.
uniq
: Returns elements that are not duplicates.
These methods return elements in sorted order:
sort
: Returns the elements, sorted by <=>
or the given block.
sort_by
: Returns the elements, sorted by the given block.
each_entry
: Calls the block with each successive element (slightly different from each).
each_with_index
: Calls the block with each successive element and its index.
each_with_object
: Calls the block with each successive element and a given object.
each_slice
: Calls the block with successive non-overlapping slices.
each_cons
: Calls the block with successive overlapping slices. (different from each_slice
).
reverse_each
: Calls the block with each successive element, in reverse order.
filter_map
: Returns truthy objects returned by the block.
flat_map
, collect_concat
: Returns flattened objects returned by the block.
grep
: Returns elements selected by a given object or objects returned by a given block.
grep_v
: Returns elements selected by a given object or objects returned by a given block.
reduce
, inject
: Returns the object formed by combining all elements.
sum
: Returns the sum of the elements, using method +
.
zip
: Combines each element with elements from other enumerables; returns the n-tuples or calls the block with each.
cycle
: Calls the block with each element, cycling repeatedly.
To use module Enumerable in a collection class:
Include it:
include Enumerable
Implement method #each
which must yield successive elements of the collection. The method will be called by almost any Enumerable method.
Example:
class Foo include Enumerable def each yield 1 yield 1, 2 yield end end Foo.new.each_entry{ |element| p element }
Output:
1 [1, 2] nil
These Ruby core classes include (or extend) Enumerable:
These Ruby standard library classes include Enumerable:
CSV
CSV::Table
CSV::Row
Virtually all methods in Enumerable call method #each
in the including class:
Hash#each
yields the next key-value pair as a 2-element Array
.
Struct#each
yields the next name-value pair as a 2-element Array
.
For the other classes above, #each
yields the next object from the collection.
The example code snippets for the Enumerable methods:
The objspace library extends the ObjectSpace
module and adds several methods to get internal statistic information about object/memory management.
You need to require 'objspace'
to use this extension module.
Generally, you SHOULD NOT use this library if you do not know about the MRI implementation. Mainly, this library is for (memory) profiler developers and MRI developers who need to know about MRI memory usage.
The ObjectSpace
module contains a number of routines that interact with the garbage collection facility and allow you to traverse all living objects with an iterator.
ObjectSpace
also provides support for object finalizers, procs that will be called after a specific object was destroyed by garbage collection. See the documentation for ObjectSpace.define_finalizer
for important information on how to use this method correctly.
a = "A" b = "B" ObjectSpace.define_finalizer(a, proc {|id| puts "Finalizer one on #{id}" }) ObjectSpace.define_finalizer(b, proc {|id| puts "Finalizer two on #{id}" }) a = nil b = nil
produces:
Finalizer two on 537763470 Finalizer one on 537763480
The DidYouMean
gem adds functionality to suggest possible method/class names upon errors such as NameError
and NoMethodError
. In Ruby 2.3 or later, it is automatically activated during startup.
@example
methosd # => NameError: undefined local variable or method `methosd' for main:Object # Did you mean? methods # method OBject # => NameError: uninitialized constant OBject # Did you mean? Object @full_name = "Yuki Nishijima" first_name, last_name = full_name.split(" ") # => NameError: undefined local variable or method `full_name' for main:Object # Did you mean? @full_name @@full_name = "Yuki Nishijima" @@full_anme # => NameError: uninitialized class variable @@full_anme in Object # Did you mean? @@full_name full_name = "Yuki Nishijima" full_name.starts_with?("Y") # => NoMethodError: undefined method `starts_with?' for "Yuki Nishijima":String # Did you mean? start_with? hash = {foo: 1, bar: 2, baz: 3} hash.fetch(:fooo) # => KeyError: key not found: :fooo # Did you mean? :foo
did_you_mean
Occasionally, you may want to disable the did_you_mean
gem for e.g. debugging issues in the error object itself. You can disable it entirely by specifying --disable-did_you_mean
option to the ruby
command:
$ ruby --disable-did_you_mean -e "1.zeor?" -e:1:in `<main>': undefined method `zeor?' for 1:Integer (NameError)
When you do not have direct access to the ruby
command (e.g. +rails console+, irb
), you could applyoptions using the RUBYOPT
environment variable:
$ RUBYOPT='--disable-did_you_mean' irb irb:0> 1.zeor? # => NoMethodError (undefined method `zeor?' for 1:Integer)
Sometimes, you do not want to disable the gem entirely, but need to get the original error message without suggestions (e.g. testing). In this case, you could use the #original_message
method on the error object:
no_method_error = begin 1.zeor? rescue NoMethodError => error error end no_method_error.message # => NoMethodError (undefined method `zeor?' for 1:Integer) # Did you mean? zero? no_method_error.original_message # => NoMethodError (undefined method `zeor?' for 1:Integer)
Timeout
long-running blocks
require 'timeout' status = Timeout::timeout(5) { # Something that should be interrupted if it takes more than 5 seconds... }
Timeout
provides a way to auto-terminate a potentially long-running operation if it hasn’t finished in a fixed amount of time.
Previous versions didn’t use a module for namespacing, however timeout
is provided for backwards compatibility. You should prefer Timeout.timeout
instead.
© 2000 Network Applied Communication Laboratory, Inc.
© 2000 Information-technology Promotion Agency, Japan
YAML
Ain’t Markup Language
This module provides a Ruby interface for data serialization in YAML
format.
The YAML
module is an alias of Psych
, the YAML
engine for Ruby.
Working with YAML
can be very simple, for example:
require 'yaml' # Parse a YAML string YAML.load("--- foo") #=> "foo" # Emit some YAML YAML.dump("foo") # => "--- foo\n...\n" { :a => 'b'}.to_yaml # => "---\n:a: b\n"
As the implementation is provided by the Psych
library, detailed documentation can be found in that library’s docs (also part of standard library).
Do not use YAML
to load untrusted data. Doing so is unsafe and could allow malicious input to execute arbitrary code inside your application. Please see doc/security.rdoc for more information.
Syck was the original YAML
implementation in Ruby’s standard library developed by why the lucky stiff.
You can still use Syck, if you prefer, for parsing and emitting YAML
, but you must install the ‘syck’ gem now in order to use it.
In older Ruby versions, ie. <= 1.9, Syck is still provided, however it was completely removed with the release of Ruby 2.0.0.
For more advanced details on the implementation see Psych
, and also check out yaml.org for spec details and other helpful information.
Psych
is maintained by Aaron Patterson on github: github.com/ruby/psych
Syck can also be found on github: github.com/ruby/syck
Many operating systems allow signals to be sent to running processes. Some signals have a defined effect on the process, while others may be trapped at the code level and acted upon. For example, your process may trap the USR1 signal and use it to toggle debugging, and may use TERM to initiate a controlled shutdown.
pid = fork do Signal.trap("USR1") do $debug = !$debug puts "Debug now: #$debug" end Signal.trap("TERM") do puts "Terminating..." shutdown() end # . . . do some work . . . end Process.detach(pid) # Controlling program: Process.kill("USR1", pid) # ... Process.kill("USR1", pid) # ... Process.kill("TERM", pid)
produces:
Debug now: true Debug now: false Terminating...
The list of available signal names and their interpretation is system dependent. Signal
delivery semantics may also vary between systems; in particular signal delivery may not always be reliable.
Enumerator::ArithmeticSequence
is a subclass of Enumerator
, that is a representation of sequences of numbers with common difference. Instances of this class can be generated by the Range#step
and Numeric#step
methods.
The class can be used for slicing Array
(see Array#slice
) or custom collections.
Raised by Encoding
and String
methods when the source encoding is incompatible with the target encoding.
WIN32OLE::Method
objects represent OLE method information.
WIN32OLE::Param
objects represent param information of the OLE method.
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.
Subclass of Zlib::Error
When zlib returns a Z_MEM_ERROR, usually if there was not enough memory.
A custom InputMethod class used by XMP
for evaluating string io.
Response class for Unauthorized
responses (status code 401).
Authentication is required, but either was not provided or failed.
References:
Response class for Payment Required
responses (status code 402).
Reserved for future use.
References:
Response class for Method Not Allowed
responses (status code 405).
The request method is not supported for the requested resource.
References:
Response class for Proxy Authentication Required
responses (status code 407).
The client must first authenticate itself with the proxy.
References:
Response class for Unsupported Media Type
responses (status code 415).
The request entity has a media type which the server or resource does not support.
References:
Response class for Gateway Timeout
responses (status code 504).
The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.
References: