The Forwardable
module provides delegation of specified methods to a designated object, using the methods def_delegator
and def_delegators
.
For example, say you have a class RecordCollection which contains an array @records
. You could provide the lookup method record_number(), which simply calls [] on the @records
array, like this:
require 'forwardable' class RecordCollection attr_accessor :records extend Forwardable def_delegator :@records, :[], :record_number end
We can use the lookup method like so:
r = RecordCollection.new r.records = [4,5,6] r.record_number(0) # => 4
Further, if you wish to provide the methods size, <<, and map, all of which delegate to @records, this is how you can do it:
class RecordCollection # re-open RecordCollection class def_delegators :@records, :size, :<<, :map end r = RecordCollection.new r.records = [1,2,3] r.record_number(0) # => 1 r.size # => 3 r << 4 # => [1, 2, 3, 4] r.map { |x| x * 2 } # => [2, 4, 6, 8]
You can even extend regular objects with Forwardable
.
my_hash = Hash.new my_hash.extend Forwardable # prepare object for delegation my_hash.def_delegator "STDOUT", "puts" # add delegation for STDOUT.puts() my_hash.puts "Howdy!"
You could use Forwardable
as an alternative to inheritance, when you don’t want to inherit all methods from the superclass. For instance, here is how you might add a range of Array
instance methods to a new class Queue
:
class Queue extend Forwardable def initialize @q = [ ] # prepare delegate object end # setup preferred interface, enq() and deq()... def_delegator :@q, :push, :enq def_delegator :@q, :shift, :deq # support some general Array methods that fit Queues well def_delegators :@q, :clear, :first, :push, :shift, :size end q = Thread::Queue.new q.enq 1, 2, 3, 4, 5 q.push 6 q.shift # => 1 while q.size > 0 puts q.deq end q.enq "Ruby", "Perl", "Python" puts q.first q.clear puts q.first
This should output:
2 3 4 5 6 Ruby nil
Be advised, RDoc
will not detect delegated methods.
forwardable.rb
provides single-method delegation via the def_delegator
and def_delegators
methods. For full-class delegation via DelegateClass, see delegate.rb
.
SingleForwardable
can be used to setup delegation at the object level as well.
printer = String.new printer.extend SingleForwardable # prepare object for delegation printer.def_delegator "STDOUT", "puts" # add delegation for STDOUT.puts() printer.puts "Howdy!"
Also, SingleForwardable
can be used to set up delegation for a Class
or Module
.
class Implementation def self.service puts "serviced!" end end module Facade extend SingleForwardable def_delegator :Implementation, :service end Facade.service #=> serviced!
If you want to use both Forwardable
and SingleForwardable
, you can use methods def_instance_delegator and def_single_delegator
, etc.
A module to implement the Linda distributed computing paradigm in Ruby.
See the sample/drb/ directory in the Ruby distribution, from 1.8.2 onwards.
Module Math provides methods for basic trigonometric, logarithmic, and transcendental functions, and for extracting roots.
You can write its constants and method calls thus:
Math::PI # => 3.141592653589793 Math::E # => 2.718281828459045 Math.sin(0.0) # => 0.0 Math.cos(0.0) # => 1.0
If you include module Math, you can write simpler forms:
include Math PI # => 3.141592653589793 E # => 2.718281828459045 sin(0.0) # => 0.0 cos(0.0) # => 1.0
For simplicity, the examples here assume:
include Math INFINITY = Float::INFINITY
The domains and ranges for the methods are denoted by open or closed intervals, using, respectively, parentheses or square brackets:
An open interval does not include the endpoints:
(-INFINITY, INFINITY)
A closed interval includes the endpoints:
[-1.0, 1.0]
A half-open interval includes one endpoint, but not the other:
[1.0, INFINITY)
Many values returned by Math methods are numerical approximations. This is because many such values are, in mathematics, of infinite precision, while in numerical computation the precision is finite.
Thus, in mathematics, cos(π/2) is exactly zero, but in our computation cos(PI/2)
is a number very close to zero:
cos(PI/2) # => 6.123031769111886e-17
For very large and very small returned values, we have added formatted numbers for clarity:
tan(PI/2) # => 1.633123935319537e+16 # 16331239353195370.0 tan(PI) # => -1.2246467991473532e-16 # -0.0000000000000001
See class Float
for the constants that affect Ruby’s floating-point arithmetic.
::cos
: Returns the cosine of the given argument.
::sin
: Returns the sine of the given argument.
::tan
: Returns the tangent of the given argument.
::acos
: Returns the arc cosine of the given argument.
::asin
: Returns the arc sine of the given argument.
::atan
: Returns the arc tangent of the given argument.
::atan2
: Returns the arg tangent of two given arguments.
::cosh
: Returns the hyperbolic cosine of the given argument.
::sinh
: Returns the hyperbolic sine of the given argument.
::tanh
: Returns the hyperbolic tangent of the given argument.
::acosh
: Returns the inverse hyperbolic cosine of the given argument.
::asinh
: Returns the inverse hyperbolic sine of the given argument.
::atanh
: Returns the inverse hyperbolic tangent of the given argument.
::exp
: Returns the value of a given value raised to a given power.
::log
: Returns the logarithm of a given value in a given base.
::log10
: Returns the base 10 logarithm of the given argument.
::log2
: Returns the base 2 logarithm of the given argument.
::frexp
: Returns the fraction and exponent of the given argument.
::ldexp
: Returns the value for a given fraction and exponent.
::cbrt
: Returns the cube root of the given argument.
::sqrt
: Returns the square root of the given argument.
::erf
: Returns the value of the Gauss error function for the given argument.
::erfc
: Returns the value of the complementary error function for the given argument.
::gamma
: Returns the value of the gamma function for the given argument.
::lgamma
: Returns the value of the logarithmic gamma function for the given argument.
::hypot
: Returns sqrt(a**2 + b**2)
for the given a
and b
.
The top-level class representing any ASN.1 object. When parsed by ASN1.decode
, tagged values are always represented by an instance of ASN1Data
.
ASN1Data
for parsing tagged values When encoding an ASN.1 type it is inherently clear what original type (e.g. INTEGER, OCTET STRING etc.) this value has, regardless of its tagging. But opposed to the time an ASN.1 type is to be encoded, when parsing them it is not possible to deduce the “real type” of tagged values. This is why tagged values are generally parsed into ASN1Data
instances, but with a different outcome for implicit and explicit tagging.
An implicitly 1-tagged INTEGER value will be parsed as an ASN1Data
with
tag equal to 1
tag_class equal to :CONTEXT_SPECIFIC
value equal to a String
that carries the raw encoding of the INTEGER.
This implies that a subsequent decoding step is required to completely decode implicitly tagged values.
An explicitly 1-tagged INTEGER value will be parsed as an ASN1Data
with
tag equal to 1
tag_class equal to :CONTEXT_SPECIFIC
value equal to an Array
with one single element, an instance of OpenSSL::ASN1::Integer
, i.e. the inner element is the non-tagged primitive value, and the tagging is represented in the outer ASN1Data
int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT) # implicit 0-tagged seq = OpenSSL::ASN1::Sequence.new( [int] ) der = seq.to_der asn1 = OpenSSL::ASN1.decode(der) # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0 # @indefinite_length=false, # @tag=16, # @tag_class=:UNIVERSAL, # @tagging=nil, # @value= # [#<OpenSSL::ASN1::ASN1Data:0x87326f4 # @indefinite_length=false, # @tag=0, # @tag_class=:CONTEXT_SPECIFIC, # @value="\x01">]> raw_int = asn1.value[0] # manually rewrite tag and tag class to make it an UNIVERSAL value raw_int.tag = OpenSSL::ASN1::INTEGER raw_int.tag_class = :UNIVERSAL int2 = OpenSSL::ASN1.decode(raw_int) puts int2.value # => 1
int = OpenSSL::ASN1::Integer.new(1, 0, :EXPLICIT) # explicit 0-tagged seq = OpenSSL::ASN1::Sequence.new( [int] ) der = seq.to_der asn1 = OpenSSL::ASN1.decode(der) # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0 # @indefinite_length=false, # @tag=16, # @tag_class=:UNIVERSAL, # @tagging=nil, # @value= # [#<OpenSSL::ASN1::ASN1Data:0x87326f4 # @indefinite_length=false, # @tag=0, # @tag_class=:CONTEXT_SPECIFIC, # @value= # [#<OpenSSL::ASN1::Integer:0x85bf308 # @indefinite_length=false, # @tag=2, # @tag_class=:UNIVERSAL # @tagging=nil, # @value=1>]>]> int2 = asn1.value[0].value[0] puts int2.value # => 1
Raised by Encoding
and String
methods when the source encoding is incompatible with the target encoding.
Wrapper for arrays within a struct
This exception is raised if a generator or unparser error occurs.
Zlib::Deflate
is the class for compressing data. See Zlib::ZStream
for more information.
Zlib:Inflate is the class for decompressing compressed data. Unlike Zlib::Deflate
, an instance of this class is not able to duplicate (clone, dup) itself.
exception to wait for reading by EAGAIN. see IO.select
.
exception to wait for writing by EAGAIN. see IO.select
.
exception to wait for reading by EWOULDBLOCK. see IO.select
.
exception to wait for writing by EWOULDBLOCK. see IO.select
.
exception to wait for reading by EINPROGRESS. see IO.select
.
exception to wait for writing by EINPROGRESS. see IO.select
.
A CSV::Table instance represents CSV data. (see class CSV).
The instance may have:
Rows: each is a Table::Row object.
Headers: names for the columns.
CSV::Table has three groups of instance methods:
Its own internally defined instance methods.
Methods included by module Enumerable
.
Methods delegated to class Array
.:
Commonly, a new CSV::Table instance is created by parsing CSV source using headers:
source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" table = CSV.parse(source, headers: true) table.class # => CSV::Table
You can also create an instance directly. See ::new
.
If a table has headers, the headers serve as labels for the columns of data. Each header serves as the label for its column.
The headers for a CSV::Table object are stored as an Array of Strings.
Commonly, headers are defined in the first row of CSV source:
source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" table = CSV.parse(source, headers: true) table.headers # => ["Name", "Value"]
If no headers are defined, the Array is empty:
table = CSV::Table.new([]) table.headers # => []
CSV::Table provides three modes for accessing table data:
Row mode.
Column mode.
Mixed mode (the default for a new table).
The access mode for aCSV::Table instance affects the behavior of some of its instance methods:
Set
a table to row mode with method by_row!
:
source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" table = CSV.parse(source, headers: true) table.by_row! # => #<CSV::Table mode:row row_count:4>
Specify a single row by an Integer index:
# Get a row. table[1] # => #<CSV::Row "Name":"bar" "Value":"1"> # Set a row, then get it. table[1] = CSV::Row.new(['Name', 'Value'], ['bam', 3]) table[1] # => #<CSV::Row "Name":"bam" "Value":3>
Specify a sequence of rows by a Range:
# Get rows. table[1..2] # => [#<CSV::Row "Name":"bam" "Value":3>, #<CSV::Row "Name":"baz" "Value":"2">] # Set rows, then get them. table[1..2] = [ CSV::Row.new(['Name', 'Value'], ['bat', 4]), CSV::Row.new(['Name', 'Value'], ['bad', 5]), ] table[1..2] # => [["Name", #<CSV::Row "Name":"bat" "Value":4>], ["Value", #<CSV::Row "Name":"bad" "Value":5>]]
Set
a table to column mode with method by_col!
:
source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" table = CSV.parse(source, headers: true) table.by_col! # => #<CSV::Table mode:col row_count:4>
Specify a column by an Integer index:
# Get a column. table[0] # Set a column, then get it. table[0] = ['FOO', 'BAR', 'BAZ'] table[0] # => ["FOO", "BAR", "BAZ"]
Specify a column by its String header:
# Get a column. table['Name'] # => ["FOO", "BAR", "BAZ"] # Set a column, then get it. table['Name'] = ['Foo', 'Bar', 'Baz'] table['Name'] # => ["Foo", "Bar", "Baz"]
In mixed mode, you can refer to either rows or columns:
An Integer index refers to a row.
A Range index refers to multiple rows.
A String index refers to a column.
Set
a table to mixed mode with method by_col_or_row!
:
source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" table = CSV.parse(source, headers: true) table.by_col_or_row! # => #<CSV::Table mode:col_or_row row_count:4>
Specify a single row by an Integer index:
# Get a row. table[1] # => #<CSV::Row "Name":"bar" "Value":"1"> # Set a row, then get it. table[1] = CSV::Row.new(['Name', 'Value'], ['bam', 3]) table[1] # => #<CSV::Row "Name":"bam" "Value":3>
Specify a sequence of rows by a Range:
# Get rows. table[1..2] # => [#<CSV::Row "Name":"bam" "Value":3>, #<CSV::Row "Name":"baz" "Value":"2">] # Set rows, then get them. table[1] = CSV::Row.new(['Name', 'Value'], ['bat', 4]) table[2] = CSV::Row.new(['Name', 'Value'], ['bad', 5]) table[1..2] # => [["Name", #<CSV::Row "Name":"bat" "Value":4>], ["Value", #<CSV::Row "Name":"bad" "Value":5>]]
Specify a column by its String header:
# Get a column. table['Name'] # => ["foo", "bat", "bad"] # Set a column, then get it. table['Name'] = ['Foo', 'Bar', 'Baz'] table['Name'] # => ["Foo", "Bar", "Baz"]
The DidYouMean::Formatter
is the basic, default formatter for the gem. The formatter responds to the message_for
method and it returns a human readable string.
The DidYouMean::Formatter
is the basic, default formatter for the gem. The formatter responds to the message_for
method and it returns a human readable string.
The DidYouMean::Formatter
is the basic, default formatter for the gem. The formatter responds to the message_for
method and it returns a human readable string.