Gem::Server
and allows users to serve gems for consumption by ‘gem –remote-install`.
gem_server starts an HTTP server on the given port and serves the following:
“/” - Browsing of gem spec files for installed gems
“/specs.#{Gem.marshal_version}.gz” - specs name/version/platform index
“/latest_specs.#{Gem.marshal_version}.gz” - latest specs name/version/platform index
“/quick/” - Individual gemspecs
“/gems” - Direct access to download the installable gems
“/rdoc?q=” - Search for installed rdoc documentation
gem_server = Gem::Server.new Gem.dir, 8089, false gem_server.run
Gem::StubSpecification
reads the stub: line from the gemspec. This prevents us having to eval the entire gemspec in order to find out certain information.
An HTTP Proxy server which proxies GET, HEAD and POST requests.
To create a simple proxy server:
require 'webrick' require 'webrick/httpproxy' proxy = WEBrick::HTTPProxyServer.new Port: 8000 trap 'INT' do proxy.shutdown end trap 'TERM' do proxy.shutdown end proxy.start
See ::new
for proxy-specific configuration items.
To modify content the proxy server returns use the :ProxyContentHandler
option:
handler = proc do |req, res| if res['content-type'] == 'text/plain' then res.body << "\nThis content was proxied!\n" end end proxy = WEBrick::HTTPProxyServer.new Port: 8000, ProxyContentHandler: handler
An HTTP Server
Base server class
Encoding
conversion class.
Mixin module that provides the following:
Access to the CGI
environment variables as methods. See documentation to the CGI
class for a list of these variables. The methods are exposed by removing the leading HTTP_
(if it exists) and downcasing the name. For example, auth_type
will return the environment variable AUTH_TYPE
, and accept
will return the value for HTTP_ACCEPT
.
Access to cookies, including the cookies attribute.
Access to parameters, including the params attribute, and overloading []
to perform parameter value lookup by key.
The initialize_query
method, for initializing the above mechanisms, handling multipart forms, and allowing the class to be used in “offline” mode.
If you add a method, keep in mind two things: (1) the first argument will always be a list of nodes from which to filter. In the case of context methods (such as position), the function should return an array with a value for each child in the array. (2) all method calls from XML
will have “-” replaced with “_”. Therefore, in XML
, “local-name()” is identical (and actually becomes) “local_name()”
Utility methods for using the RubyGems API.
Arrays are ordered, integer-indexed collections of any object.
Array
indexing starts at 0, as in C or Java. A negative index is assumed to be relative to the end of the array—that is, an index of -1 indicates the last element of the array, -2 is the next to last element in the array, and so on.
A new array can be created by using the literal constructor []
. Arrays can contain different types of objects. For example, the array below contains an Integer
, a String
and a Float:
ary = [1, "two", 3.0] #=> [1, "two", 3.0]
An array can also be created by explicitly calling Array.new
with zero, one (the initial size of the Array
) or two arguments (the initial size and a default object).
ary = Array.new #=> [] Array.new(3) #=> [nil, nil, nil] Array.new(3, true) #=> [true, true, true]
Note that the second argument populates the array with references to the same object. Therefore, it is only recommended in cases when you need to instantiate arrays with natively immutable objects such as Symbols, numbers, true or false.
To create an array with separate objects a block can be passed instead. This method is safe to use with mutable objects such as hashes, strings or other arrays:
Array.new(4) {Hash.new} #=> [{}, {}, {}, {}] Array.new(4) {|i| i.to_s } #=> ["0", "1", "2", "3"]
This is also a quick way to build up multi-dimensional arrays:
empty_table = Array.new(3) {Array.new(3)} #=> [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
An array can also be created by using the Array() method, provided by Kernel
, which tries to call to_ary
, then to_a
on its argument.
Array({:a => "a", :b => "b"}) #=> [[:a, "a"], [:b, "b"]]
In addition to the methods it mixes in through the Enumerable
module, the Array
class has proprietary methods for accessing, searching and otherwise manipulating arrays.
Some of the more common ones are illustrated below.
Elements in an array can be retrieved using the Array#[]
method. It can take a single integer argument (a numeric index), a pair of arguments (start and length) or a range. Negative indices start counting from the end, with -1 being the last element.
arr = [1, 2, 3, 4, 5, 6] arr[2] #=> 3 arr[100] #=> nil arr[-3] #=> 4 arr[2, 3] #=> [3, 4, 5] arr[1..4] #=> [2, 3, 4, 5] arr[1..-3] #=> [2, 3, 4]
Another way to access a particular array element is by using the at
method
arr.at(0) #=> 1
The slice
method works in an identical manner to Array#[]
.
To raise an error for indices outside of the array bounds or else to provide a default value when that happens, you can use fetch
.
arr = ['a', 'b', 'c', 'd', 'e', 'f'] arr.fetch(100) #=> IndexError: index 100 outside of array bounds: -6...6 arr.fetch(100, "oops") #=> "oops"
The special methods first
and last
will return the first and last elements of an array, respectively.
arr.first #=> 1 arr.last #=> 6
To return the first n
elements of an array, use take
arr.take(3) #=> [1, 2, 3]
drop
does the opposite of take
, by returning the elements after n
elements have been dropped:
arr.drop(3) #=> [4, 5, 6]
Array
Arrays keep track of their own length at all times. To query an array about the number of elements it contains, use length
, count
or size
.
browsers = ['Chrome', 'Firefox', 'Safari', 'Opera', 'IE'] browsers.length #=> 5 browsers.count #=> 5
To check whether an array contains any elements at all
browsers.empty? #=> false
To check whether a particular item is included in the array
browsers.include?('Konqueror') #=> false
Items can be added to the end of an array by using either push
or <<
arr = [1, 2, 3, 4] arr.push(5) #=> [1, 2, 3, 4, 5] arr << 6 #=> [1, 2, 3, 4, 5, 6]
unshift
will add a new item to the beginning of an array.
arr.unshift(0) #=> [0, 1, 2, 3, 4, 5, 6]
With insert
you can add a new element to an array at any position.
arr.insert(3, 'apple') #=> [0, 1, 2, 'apple', 3, 4, 5, 6]
Using the insert
method, you can also insert multiple values at once:
arr.insert(3, 'orange', 'pear', 'grapefruit') #=> [0, 1, 2, "orange", "pear", "grapefruit", "apple", 3, 4, 5, 6]
Array
The method pop
removes the last element in an array and returns it:
arr = [1, 2, 3, 4, 5, 6] arr.pop #=> 6 arr #=> [1, 2, 3, 4, 5]
To retrieve and at the same time remove the first item, use shift
:
arr.shift #=> 1 arr #=> [2, 3, 4, 5]
To delete an element at a particular index:
arr.delete_at(2) #=> 4 arr #=> [2, 3, 5]
To delete a particular element anywhere in an array, use delete
:
arr = [1, 2, 2, 3] arr.delete(2) #=> 2 arr #=> [1,3]
A useful method if you need to remove nil
values from an array is compact
:
arr = ['foo', 0, nil, 'bar', 7, 'baz', nil] arr.compact #=> ['foo', 0, 'bar', 7, 'baz'] arr #=> ['foo', 0, nil, 'bar', 7, 'baz', nil] arr.compact! #=> ['foo', 0, 'bar', 7, 'baz'] arr #=> ['foo', 0, 'bar', 7, 'baz']
Another common need is to remove duplicate elements from an array.
It has the non-destructive uniq
, and destructive method uniq!
arr = [2, 5, 6, 556, 6, 6, 8, 9, 0, 123, 556] arr.uniq #=> [2, 5, 6, 556, 8, 9, 0, 123]
Like all classes that include the Enumerable
module, Array
has an each method, which defines what elements should be iterated over and how. In case of Array’s each
, all elements in the Array
instance are yielded to the supplied block in sequence.
Note that this operation leaves the array unchanged.
arr = [1, 2, 3, 4, 5] arr.each {|a| print a -= 10, " "} # prints: -9 -8 -7 -6 -5 #=> [1, 2, 3, 4, 5]
Another sometimes useful iterator is reverse_each
which will iterate over the elements in the array in reverse order.
words = %w[first second third fourth fifth sixth] str = "" words.reverse_each {|word| str += "#{word} "} p str #=> "sixth fifth fourth third second first "
The map
method can be used to create a new array based on the original array, but with the values modified by the supplied block:
arr.map {|a| 2*a} #=> [2, 4, 6, 8, 10] arr #=> [1, 2, 3, 4, 5] arr.map! {|a| a**2} #=> [1, 4, 9, 16, 25] arr #=> [1, 4, 9, 16, 25]
Array
Elements can be selected from an array according to criteria defined in a block. The selection can happen in a destructive or a non-destructive manner. While the destructive operations will modify the array they were called on, the non-destructive methods usually return a new array with the selected elements, but leave the original array unchanged.
arr = [1, 2, 3, 4, 5, 6] arr.select {|a| a > 3} #=> [4, 5, 6] arr.reject {|a| a < 3} #=> [3, 4, 5, 6] arr.drop_while {|a| a < 4} #=> [4, 5, 6] arr #=> [1, 2, 3, 4, 5, 6]
select!
and reject!
are the corresponding destructive methods to select
and reject
Similar to select
vs. reject
, delete_if
and keep_if
have the exact opposite result when supplied with the same block:
arr.delete_if {|a| a < 4} #=> [4, 5, 6] arr #=> [4, 5, 6] arr = [1, 2, 3, 4, 5, 6] arr.keep_if {|a| a < 4} #=> [1, 2, 3] arr #=> [1, 2, 3]
for pack.c
Holds Integer
values. You cannot add a singleton method to an Integer
object, any attempt to do so will raise a TypeError
.
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
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
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
You can use this 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 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"
Raised when a given numerical value is out of range.
[1, 2, 3].drop(1 << 100)
raises the exception:
RangeError: bignum too big to convert into `long'
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