<ppdoc>
<copyright>
    Copyright (c) 2001 by Addison Wesley Longman.  This
    material may be distributed only subject to the terms and
    conditions set forth in the Open Publication License, v1.0 or
    later (the latest version is presently available at
    http://www.opencontent.org/openpub/).
</copyright>
<chapter  ref="xref-000013" name="Standard Library">
<p/>
Ruby comes ``out of the box'' with a large and useful library of
modules and classes. This chapter contains a sampling of the more
useful of these.
<p/>
Interestingly, and unlike some of the code in later chapters, all of
these libraries are written in Ruby. You'll find the source in the
<tt>lib</tt> subdirectory of the standard Ruby distribution.
<p/>
<class name="Complex" super="Numeric" type="class" ref="xref-000001">
<p/>
<codefragment>
<fullcode><![CDATA[      require "complex"
      
      v1 = Complex(2,3)
      v2 = 2.im
      v1 + v2
      v1 * v2
      v2**2
      Math.sin(v1)
      v1 < v2
      v2**2 == -4
]]></fullcode><rubycode>
<tr>
<td colspan="3"><tt>require<nbsp/>"complex"</tt></td>
</tr>
<tr>
<td colspan="3"><tt></tt></td>
</tr>
<tr>
  <td><tt>v1<nbsp/>=<nbsp/>Complex(2,3)</tt></td>
  <td>&#187;</td>
  <td><tt>Complex(2,<nbsp/>3)</tt></td>
</tr>
<tr>
  <td><tt>v2<nbsp/>=<nbsp/>2.im</tt></td>
  <td>&#187;</td>
  <td><tt>Complex(0,<nbsp/>2)</tt></td>
</tr>
<tr>
  <td><tt>v1<nbsp/>+<nbsp/>v2</tt></td>
  <td>&#187;</td>
  <td><tt>Complex(2,<nbsp/>5)</tt></td>
</tr>
<tr>
  <td><tt>v1<nbsp/>*<nbsp/>v2</tt></td>
  <td>&#187;</td>
  <td><tt>Complex(-6,<nbsp/>4)</tt></td>
</tr>
<tr>
  <td><tt>v2**2</tt></td>
  <td>&#187;</td>
  <td><tt>Complex(-4,<nbsp/>0)</tt></td>
</tr>
<tr>
  <td><tt>Math.sin(v1)</tt></td>
  <td>&#187;</td>
  <td><tt>Complex(9.154499147,<nbsp/>-4.16890696)</tt></td>
</tr>
<tr>
  <td><tt>v1<nbsp/>&lt;<nbsp/>v2</tt></td>
  <td>&#187;</td>
  <td><tt>false</tt></td>
</tr>
<tr>
  <td><tt>v2**2<nbsp/>==<nbsp/>-4</tt></td>
  <td>&#187;</td>
  <td><tt>true</tt></td>
</tr>
</rubycode>
<p/>
</codefragment>
<p/>
  <constants>
<tr>
  <td><constant>
       <constname>Complex::I</constname>
       <constval></constval>
       <constdesc>0 +1<sub>i</sub></constdesc>
     </constant>
</td>
</tr>
</constants>
<p/>
  <methods type="class">
        <method name="new" ref="new">
      <callseq>
        Complex.new( <obj>a</obj>, <obj>b</obj> )
        <returns><obj>aComplex</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns a + b<sub>i</sub>.
<p/>
      </desc>
    </method>
<p/>
  </methods>
<p/>
  In addition to the <ccm><front>Complex</front><back>new</back></ccm> constructor, the <classname>Complex</classname>
  library defines the method <ccm><file>numeric</file><front>Numeric</front><back>im</back><mref>im</mref></ccm>, such that
  <obj>aNumeric</obj><tt>.im</tt> returns 0 + <obj>aNumeric</obj><sub>i</sub>. Complex
  numbers are also constructed using the global method
  <meth>Complex</meth>, which takes one or two arguments. The value it
  returns depends on the type of its arguments:
<p/>
  <table>
<th>
  <td><b>a</b></td>
  <td><b>b</b></td>
  <td><b>Result</b></td>
</th>
<tr>
  <td>Number</td>
  <td>Number</td>
  <td> a + b<sub>i</sub> </td>
</tr>
<tr>
  <td>Complex</td>
  <td>0</td>
  <td><obj>a</obj></td>
</tr>
<tr>
  <td>Complex</td>
  <td>Complex</td>
  <td><tt>Complex( <obj>a</obj>.real - <obj>b</obj>.image,
                                     <obj>a</obj>.image + <obj>b</obj>.real )</tt></td>
</tr>
<tr>
  <td>Number</td>
  <td>Complex</td>
  <td><tt>Complex( <obj>a</obj> - <obj>b</obj>.image,
                                     <obj>b</obj>.real )</tt></td>
</tr>
<bottomrule/></table>
<p/>
  <methods type="instance">
        <method name="Arithmetic operations" ref="Arithmeticoperations">
      <callseq>
<p/>
      </callseq>
      <desc>
<p/>
      Performs various arithmetic operations on <obj>ref</obj>.
<p/>
      <table>
<tr>
  <td><obj>ref</obj></td>
  <td>+</td>
  <td><obj>aNumeric</obj>
        <returns><obj>aComplex</obj></returns></td>
  <td>Addition</td>
</tr>
<tr>
  <td><obj>ref</obj></td>
  <td>-</td>
  <td><obj>aNumeric</obj>
        <returns><obj>aComplex</obj></returns></td>
  <td>Subtraction</td>
</tr>
<tr>
  <td><obj>ref</obj></td>
  <td>*</td>
  <td><obj>aNumeric</obj>
        <returns><obj>aComplex</obj></returns></td>
  <td>Multiplication</td>
</tr>
<tr>
  <td><obj>ref</obj></td>
  <td>/</td>
  <td><obj>aNumeric</obj>
        <returns><obj>aComplex</obj></returns></td>
  <td>Division</td>
</tr>
<tr>
  <td><obj>ref</obj></td>
  <td>%</td>
  <td><obj>aNumeric</obj>
        <returns><obj>aComplex</obj></returns></td>
  <td>Remainder</td>
</tr>
<tr>
  <td><obj>ref</obj></td>
  <td>**</td>
  <td><obj>aNumeric</obj>
        <returns><obj>aComplex</obj></returns></td>
  <td>Exponentiation (real and
        complex power)</td>
</tr>
</table>
<p/>
      </desc>
    </method>
<p/>
        <method name="&lt;=&gt;" ref="_lt_eq_lt">
      <callseq>
        <obj>ref</obj> &lt;=&gt; <obj>other</obj> <returns>-1, 0, +1</returns>
      </callseq>
      <desc>
<p/>
      Returns <obj>ref</obj>.abs <tt>&lt;=&gt;</tt> <obj>other</obj>.abs.
<p/>
      </desc>
    </method>
<p/>
        <method name="==" ref="_eq_eq">
      <callseq>
        <obj>ref</obj> == <obj>anObject</obj> <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      If <obj>anObject</obj> is a complex number, returns <const>true</const> if
      its real and imaginary parts match <obj>ref</obj>. If <obj>anObject</obj> is a
      simple number, returns <const>true</const> if
      <obj>ref</obj>.<tt>real</tt> equals <obj>anObject</obj> and
      <obj>ref</obj>.<tt>image</tt> is zero. Otherwise, attempts to
      coerce <obj>anObject</obj> to a complex number and compares the result.
<p/>
      </desc>
    </method>
<p/>
        <method name="abs" ref="abs">
      <callseq>
        <obj>ref</obj>.abs <returns><obj>aFloat</obj></returns>
      </callseq>
      <desc>
<p/>
      Absolute value.
<p/>
      </desc>
    </method>
<p/>
        <method name="abs2" ref="abs2">
      <callseq>
        <obj>ref</obj>.abs2 <returns><obj>aFloat</obj></returns>
      </callseq>
      <desc>
<p/>
      Square of absolute value.
<p/>
      </desc>
    </method>
<p/>
        <method name="arg" ref="arg">
      <callseq>
        <obj>ref</obj>.arg <returns><obj>aFloat</obj></returns>
      </callseq>
      <desc>
<p/>
      Argument (angle from (1,0)).
<p/>
      </desc>
    </method>
<p/>
        <method name="conjugate" ref="conjugate">
      <callseq>
        <obj>ref</obj>.conjugate
        <returns><obj>aComplex</obj></returns>
      </callseq>
      <desc>
<p/>
      Complex conjugate.
<p/>
      </desc>
    </method>
<p/>
        <method name="image" ref="image">
      <callseq>
        <obj>ref</obj>.image <returns><obj>aNumeric</obj></returns>
      </callseq>
      <desc>
<p/>
      The imaginary part of <obj>ref</obj>.
<p/>
      </desc>
    </method>
<p/>
        <method name="polar" ref="polar">
      <callseq>
        <obj>ref</obj>.polar <returns><obj>anArray</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns the two-element array: [<obj>c</obj>.abs, <obj>c</obj>.arg].
<p/>
      </desc>
    </method>
<p/>
        <method name="real" ref="real">
      <callseq>
        <obj>ref</obj>.real <returns><obj>aNumeric</obj></returns>
      </callseq>
      <desc>
<p/>
      The real part of <obj>ref</obj>.
<p/>
      </desc>
    </method>
<p/>
        <method name="to_f" ref="to_f">
      <callseq>
        <obj>ref</obj>.to_f <returns><obj>aComplex</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns <tt>Complex(real.to_f, image.to_f)</tt>.
<p/>
      </desc>
    </method>
<p/>
        <method name="to_i" ref="to_i">
      <callseq>
        <obj>ref</obj>.to_i <returns><obj>aComplex</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns <tt>Complex(real.to_i, image.to_i)</tt>.
<p/>
      </desc>
    </method>
<p/>
        <method name="to_r" ref="to_r">
      <callseq>
        <obj>ref</obj>.to_r <returns><obj>aComplex</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns <tt>Complex(real.to_r, image.to_r)</tt>, converting both
      parts of the complex to a rational number.
<p/>
      </desc>
    </method>
<p/>
        <method name="to_s" ref="to_s">
      <callseq>
        <obj>ref</obj>.to_s <returns><obj>aString</obj></returns>
      </callseq>
      <desc>
<p/>
      String representation of <obj>ref</obj>.
<p/>
      </desc>
    </method>
<p/>
  </methods>
<p/>
In addition, the <modulename>Math</modulename> functions <meth>sqrt</meth>, <meth>exp</meth>, <meth>cos</meth>,
<meth>sin</meth>, <meth>tan</meth>, <meth>log</meth>, <meth>log10</meth>, and <meth>atan2</meth> are
extended to support a <classname>Complex</classname> argument.
</class>
<p/>
<class name="Date" super="Object" type="class" ref="xref-000002">
<p/>
<codefragment>
<fullcode><![CDATA[      require 'date'
      
      d = Date.new(2000, 3, 31)
      [d.year, d.yday, d.wday]
      [d.month, d.mday]
      [d.cwyear, d.cweek, d.cwday]
      [d.jd, d.mjd]
      (d << 1).to_s
      d.succ.to_s
      (d + 100).to_s
      d.leap?
      Date.new(2000, 3, -10).to_s
      d1 = Date.neww(2000, 13, 7)
      d1.to_s
      [d1.cwday, d1.wday]
]]></fullcode><rubycode>
<tr>
<td colspan="3"><tt>require<nbsp/>'date'</tt></td>
</tr>
<tr>
<td colspan="3"><tt></tt></td>
</tr>
<tr>
  <td><tt>d<nbsp/>=<nbsp/>Date.new(2000,<nbsp/>3,<nbsp/>31)</tt></td>
  <td>&#187;</td>
  <td><tt>#&lt;Date:<nbsp/>2451635,2299161&gt;</tt></td>
</tr>
<tr>
  <td><tt>[d.year,<nbsp/>d.yday,<nbsp/>d.wday]</tt></td>
  <td>&#187;</td>
  <td><tt>[2000,<nbsp/>91,<nbsp/>5]</tt></td>
</tr>
<tr>
  <td><tt>[d.month,<nbsp/>d.mday]</tt></td>
  <td>&#187;</td>
  <td><tt>[3,<nbsp/>31]</tt></td>
</tr>
<tr>
  <td><tt>[d.cwyear,<nbsp/>d.cweek,<nbsp/>d.cwday]</tt></td>
  <td>&#187;</td>
  <td><tt>[2000,<nbsp/>13,<nbsp/>5]</tt></td>
</tr>
<tr>
  <td><tt>[d.jd,<nbsp/>d.mjd]</tt></td>
  <td>&#187;</td>
  <td><tt>[2451635,<nbsp/>51634.5]</tt></td>
</tr>
<tr>
  <td><tt>(d<nbsp/>&lt;&lt;<nbsp/>1).to_s</tt></td>
  <td>&#187;</td>
  <td><tt>"2000-02-29"</tt></td>
</tr>
<tr>
  <td><tt>d.succ.to_s</tt></td>
  <td>&#187;</td>
  <td><tt>"2000-04-01"</tt></td>
</tr>
<tr>
  <td><tt>(d<nbsp/>+<nbsp/>100).to_s</tt></td>
  <td>&#187;</td>
  <td><tt>"2000-07-09"</tt></td>
</tr>
<tr>
  <td><tt>d.leap?</tt></td>
  <td>&#187;</td>
  <td><tt>true</tt></td>
</tr>
<tr>
  <td><tt>Date.new(2000,<nbsp/>3,<nbsp/>-10).to_s</tt></td>
  <td>&#187;</td>
  <td><tt>"2000-03-22"</tt></td>
</tr>
<tr>
  <td><tt>d1<nbsp/>=<nbsp/>Date.neww(2000,<nbsp/>13,<nbsp/>7)</tt></td>
  <td>&#187;</td>
  <td><tt>#&lt;Date:<nbsp/>2451637,2299161&gt;</tt></td>
</tr>
<tr>
  <td><tt>d1.to_s</tt></td>
  <td>&#187;</td>
  <td><tt>"2000-04-02"</tt></td>
</tr>
<tr>
  <td><tt>[d1.cwday,<nbsp/>d1.wday]</tt></td>
  <td>&#187;</td>
  <td><tt>[7,<nbsp/>0]</tt></td>
</tr>
</rubycode>
<p/>
</codefragment>
<p/>
  The <tt>date</tt> library implements class <classname>Date</classname>, which provides a
  comprehensive set of facilities for storing, manipulating, and
  converting dates. To document its options, we need to take a brief
  historical detour to establish some vocabulary.
<p/>
  Internally a date is stored as a Julian day number, the number of
  days since midday, January 1st, 4713<nbsp/>BCE.<footnote>In
    the code, you may find references to the year -4712. As astronomical
    dates include a year zero, 4713<nbsp/>BCE is the same year as
    -4712.</footnote> The rules for converting a Julian day number to a
  calendar date are complicated because the Romans estimated the
  length of a year incorrectly. In the Julian calendar (often called
  Old Style, or O.S.), every year divisible by 4 is a leap year.
  The <classname>Date</classname> class has options to convert dates using this as an
  assumption.
<p/>
  By the sixteenth century, the inaccuracies in this measurement had
  become apparent. An edict from Pope Gregory<nbsp/>XIII in 1582 created the
  New Style (N.S.) or Gregorian calendar, where years divisible by 100 were no
  longer leap years unless they were also divisible by 400. This system was
  adopted by most Catholic countries immediately, but religious
  differences held up a wider adoption. England (and several other
  countries) switched in 1752, with some countries following later.
  The <classname>Date</classname> class allows you to determine whether to implement the
  cutover in 1582 (the <const>Date::ITALY</const> option), 1752
  (<const>Date::ENGLAND</const>), or another date of your choosing.    
<p/>
  The <classname>Date</classname> class also provides conversions to Modified Julian Day
  (MJD) numbers.
  MJD values count from midnight, November 17, 1858. Because these
  values count from midnight, not midday, there is a half-day added to the
  conversion factor.
<p/>
  The descriptions that follow use the abbreviations listed
  in Table 24.1 on page 441.
<p/>
  <figure type="table">
    <caption>Abbreviations used describing dates</caption>
<p/>
<table>
<th>
  <td><b>Field</b></td>
  <td><b>Meaning</b></td>
</th>
<tr>
  <td>cwday</td>
  <td>An ISO<nbsp/>8601 calendar weekday. 1 is Monday, 7 is Sunday.</td>
</tr>
<tr>
  <td>cweek</td>
  <td>An ISO<nbsp/>8601 calendar week. Week 1 is the week containing the
  first Thursday (or equivalently the week that contains
  January<nbsp/>4th).</td>
</tr>
<tr>
  <td>cwyear</td>
  <td>An ISO<nbsp/>8601 calendar-week-based year. May be different from
  <obj>year</obj>, as it rolls forward only on a Monday.</td>
</tr>
<tr>
  <td>jd</td>
  <td>The Julian day number---the number of days since January
  1st, 4713<nbsp/>BCE.</td>
</tr>
<tr>
  <td>mday</td>
  <td>The day of the month (1..31).</td>
</tr>
<tr>
  <td>mjd</td>
  <td>A modified Julian day number.</td>
</tr>
<tr>
  <td>mon</td>
  <td>The month of the year (1..12).</td>
</tr>
<tr>
  <td>sg</td>
  <td>The start of the Gregorian correction: <const>Date::ITALY</const> (the
  default) for 1582, <const>Date::ENGLAND</const> for 1752, or
  <const>JULIAN</const>, meaning no correction. You may also provide an
  arbitrary Julian day number for this parameter, in which case the
  correction will start from this date.</td>
</tr>
<tr>
  <td>wday</td>
  <td>The day of the week (0 is Sunday).</td>
</tr>
<tr>
  <td>week</td>
  <td>The week number into a year (1..53).</td>
</tr>
<tr>
  <td>yday</td>
  <td>The day into the year (1..366).</td>
</tr>
<tr>
  <td>year</td>
  <td>A year (1966, 2001, and the like).</td>
</tr>
<bottomrule/></table>
<p/>
</figure>
<p/>
Class <classname>Date</classname> exports the constant arrays <const>Date::MONTHNAMES</const>
and <const>Date::DAYNAMES</const>, which can be indexed by <obj>mon</obj> and
<obj>wday</obj> values to return the corresponding English names.
<p/>
The <classname>Date</classname> class also provides low-level date-conversion methods:
<p/>
<center>
<table>
<tr>
  <td>*<nbsp/><meth>civil_to_jd</meth></td>
  <td>*<nbsp/><meth>jd_to_civil</meth></td>
</tr>
<tr>
  <td>*<nbsp/><meth>commercial_to_jd</meth></td>
  <td>*<nbsp/><meth>jd_to_commercial</meth></td>
</tr>
<tr>
  <td>*<nbsp/><meth>ordinal_to_jd</meth></td>
  <td>*<nbsp/><meth>jd_to_ordinal</meth></td>
</tr>
<tr>
  <td>*<nbsp/><meth>jd_to_mjd</meth></td>
  <td>*<nbsp/><meth>mjd_to_jd</meth></td>
</tr>
</table>
<p/>
</center>
<p/>
These methods perform limited error checking of their parameters, and are not
documented here.  The somewhat confusingly named <tt>exist..?</tt>
routines perform conversions from different formats into a Julian day
number with error checking. These routines also automatically
normalize their parameters.
<p/>
  <mixins>
    <mixin name="Comparable">
   &lt;, &lt;=, ==, &gt;=, &gt;, between?</mixin>
  </mixins>
<p/>
  <methods type="class">
<p/>
        <method name="exist2?" ref="exist2_qm">
      <callseq>
        Date.exist2?(
        <obj>year</obj>, <obj>yday</obj>, <obj>sg</obj>=<const>Date::ITALY</const>) <returns><obj>jd</obj></returns>
      </callseq>
      <desc>
<p/>
      Converts a <obj>year</obj> and <obj>yday</obj> into a Julian day number,
      returning <tt>nil</tt> on error.
<p/>
      </desc>
    </method>
<p/>
        <method name="exist?" ref="exist_qm">
      <callseq>
        Date.exist?( <obj>year</obj>, <obj>mon</obj>,
        <obj>mday</obj>,  <obj>sg</obj>=<const>Date::ITALY</const>) <returns><obj>jd</obj></returns>
      </callseq>
      <desc>
<p/>
      Converts a <obj>year</obj>, <obj>mon</obj>, and <obj>mday</obj> into a Julian day
      number, or <tt>nil</tt> if the parameters are invalid.
<p/>
      </desc>
    </method>
<p/>
        <method name="existw?" ref="existw_qm">
      <callseq>
        Date.existw?(
        <obj>cyear</obj>, <obj>cweek</obj>, <obj>cwday</obj>, <obj>sg</obj>=<const>Date::ITALY</const>)
        <returns><obj>jd</obj></returns>
      </callseq>
      <desc>
         Converts a <obj>cyear</obj>,
       <obj>cweek</obj>, and <obj>cwday</obj> into a Julian day number. 
<p/>
      </desc>
    </method>
<p/>
        <method name="gregorian_leap?" ref="gregorian_leap_qm">
      <callseq>
        Date.gregorian_leap?( <obj>year</obj> 
        ) <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      If <obj>year</obj> does not end with ``00'', returns <const>true</const> if 
      <obj>year</obj> is divisible by 4, otherwise returns <const>true</const> 
      if <obj>year</obj> is divisible by 400.
<p/>
      </desc>
    </method>
<p/>
        <method name="julian_leap?" ref="julian_leap_qm">
      <callseq>
        Date.julian_leap?( <obj>year</obj> )
        <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Returns <const>true</const> if <obj>year</obj> is divisible by 4.
<p/>
      </desc>
    </method>
<p/>
        <method name="leap?" ref="leap_qm">
      <callseq>
        Date.leap?( <obj>year</obj> ) <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Synonym for <ccm><front>Date</front><back>gregorian_leap?</back></ccm>.
<p/>
      </desc>
    </method>
<p/>
        <method name="new" ref="new">
      <callseq>
        Date.new( <obj>year</obj>=-4712, <obj>mon</obj>=1, <obj>mday</obj>=1,
        <obj>sg</obj>=<const>Date::ITALY</const>) <returns><obj>aNewDate</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns a <classname>Date</classname> for the given <obj>year</obj>, <obj>mon</obj>, and
      <obj>mday</obj>. If <obj>mon</obj> is negative, it counts back from the end of the 
      year. If <obj>mday</obj> is negative, it counts back from the
      end of the month.
<p/>
      </desc>
    </method>
<p/>
        <method name="new1" ref="new1">
      <callseq>
        Date.new1( <obj>jd</obj>, <obj>sg</obj>=<const>Date::ITALY</const>)
        <returns><obj>aNewDate</obj></returns>
      </callseq>
      <desc>
<p/>
      Creates a <classname>Date</classname> corresponding to the given Julian day
      number.
<p/>
      </desc>
    </method>
<p/>
        <method name="new2" ref="new2">
      <callseq>
        Date.new2( <obj>year</obj>=-4712, <obj>yday</obj>=1,
        <obj>sg</obj>=<const>Date::ITALY</const>) <returns><obj>aNewDate</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns a <classname>Date</classname> for the given <obj>year</obj> and
      <obj>yday</obj>. If <obj>yday</obj> is negative, it counts back from the
      end of the year.
<p/>
      </desc>
    </method>
<p/>
        <method name="new3" ref="new3">
      <callseq>
        Date.new3( <obj>year</obj>=-4712, <obj>mon</obj>=1, <obj>mday</obj>=1,
        <obj>sg</obj>=<const>Date::ITALY</const>) <returns><obj>aNewDate</obj></returns>
      </callseq>
      <desc>
<p/>
      Synonym for <ccm><front>Date</front><back>new</back></ccm>.
<p/>
      </desc>
    </method>
<p/>
        <method name="neww" ref="neww">
      <callseq>
        Date.neww( <obj>cyear</obj>=1582, <obj>cweek</obj>=41,
        <obj>cwday</obj>=5, <obj>sg</obj>=<const>Date::ITALY</const>) <returns><obj>aNewDate</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns
      a <classname>Date</classname> for the given <obj>cyear</obj>, <obj>cweek</obj>, and
      <obj>cwday</obj>. If <obj>cweek</obj> is negative, it counts back from the end
      of the year. If <obj>cwday</obj> is negative, it counts back
      from the end of the week.
<p/>
      </desc>
    </method>
<p/>
        <method name="today" ref="today">
      <callseq>
        Date.today( <obj>sg</obj>=<const>Date::ITALY</const>)
        <returns><obj>aNewDate</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns a <classname>Date</classname> for today.
<p/>
      </desc>
    </method>
<p/>
  </methods>
<p/>
  <methods type="instance">
        <method name="Accessors" ref="Accessors">
      <callseq>
                  <obj>ref</obj>.year <returns><obj>year</obj></returns><br/><obj>ref</obj>.yday <returns><obj>yday</obj></returns><br/><obj>ref</obj>.mjd <returns><obj>mjd</obj></returns><br/><obj>ref</obj>.mon <returns><obj>mon</obj></returns><br/><obj>ref</obj>.month <returns><obj>mon</obj></returns><br/><obj>ref</obj>.mday <returns><obj>mday</obj></returns><br/><obj>ref</obj>.day <returns><obj>mday</obj></returns><br/><obj>ref</obj>.cwyear <returns><obj>cwyear</obj></returns><br/><obj>ref</obj>.cweek <returns><obj>cweek</obj></returns><br/><obj>ref</obj>.cwday <returns><obj>cwday</obj></returns><br/><obj>ref</obj>.wday <returns><obj>wday</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns the given component of <obj>ref</obj> as a number.
<p/>
      </desc>
    </method>
<p/>
        <method name="+" ref="_pl">
      <callseq>
        <obj>ref</obj> + <obj>anInteger</obj>
        <returns><obj>aNewDate</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns a new <classname>Date</classname> <obj>anInteger</obj> days from <obj>ref</obj>.
<p/>
      </desc>
    </method>
<p/>
        <method name="--" ref="_mi_mi">
      <callseq>
                  <obj>ref</obj> <tt>-</tt> <obj>anInteger</obj> <returns><obj>aNewDate</obj></returns><br/><obj>ref</obj> <tt>-</tt> <obj>anOtherDate</obj> <returns><obj>anInteger</obj></returns>
      </callseq>
      <desc>
<p/>
      The first form returns a new <classname>Date</classname> <obj>anInteger</obj> days
      before <obj>ref</obj>.
      The second form 
      returns the number of days between <obj>ref</obj> and <obj>anOtherDate</obj>.
<p/>
      </desc>
    </method>
<p/>
        <method name="&lt;&lt;" ref="_lt_lt">
      <callseq>
        <obj>ref</obj> &lt;&lt; <obj>anInteger</obj> <returns><obj>aNewDate</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns a new <classname>Date</classname> formed by subtracting <obj>anInteger</obj> months to <obj>ref</obj>,
      adjusting the <obj>mday</obj> value back to the last day of the month if it
      otherwise exceeds it.
<p/>
      </desc>
    </method>
<p/>
        <method name="&lt;=&gt;" ref="_lt_eq_lt">
      <callseq>
        <obj>ref</obj> &lt;=&gt; <obj>anOther</obj> <returns>-1, 0, +1</returns>
      </callseq>
      <desc>
<p/>
      <obj>anOther</obj> must be a <classname>Numeric</classname>, in which case it is
      treated as
      a Julian day number, or a <classname>Date</classname>.
      Returns -1, 0, +1 if <obj>ref</obj> is
      less than, equal to, or greater than <obj>anOther</obj>. See module
      <modulename>Comparable</modulename> on page 402.
<p/>
      </desc>
    </method>
<p/>
        <method name="===" ref="_eq_eq_eq">
      <callseq>
        <obj>ref</obj> === <obj>anOther</obj> <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      <obj>anOther</obj> must be a <classname>Numeric</classname>, in which case it is
      treated as
      a Julian day number, or a <classname>Date</classname>.
      Returns <const>true</const> if the
      Julian day number of <obj>anOther</obj> is the same as <obj>ref</obj>.
<p/>
      </desc>
    </method>
<p/>
        <method name="&gt;&gt;" ref="_lt_lt">
      <callseq>
        <obj>ref</obj> &gt;&gt; <obj>anInteger</obj> <returns><obj>aNewDate</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns a new <classname>Date</classname> formed by adding <obj>anInteger</obj> months to <obj>ref</obj>,
      adjusting the <obj>mday</obj> value back to the last day of the month if it
      otherwise exceeds it.
<p/>
      </desc>
    </method>
<p/>
        <method name="downto" ref="downto">
      <callseq>
        <obj>ref</obj>.downto( <obj>aDateMin</obj> )
        <block>{| date | <blockbody>block</blockbody> }</block>
<p/>
        <returns><obj>ref</obj></returns>
      </callseq>
      <desc>
<p/>
    Invokes block with dates from <obj>ref</obj> down to <obj>aDateMin</obj>.
<p/>
      </desc>
    </method>
<p/>
        <method name="england" ref="england">
      <callseq>
        <obj>ref</obj>.england <returns><obj>aDate</obj></returns>
      </callseq>
      <desc>
<p/>
      Equivalent to <obj>ref</obj><tt>.newsg(Date::ENGLAND)</tt>.
<p/>
      </desc>
    </method>
<p/>
        <method name="gregorian" ref="gregorian">
      <callseq>
        <obj>ref</obj>.gregorian
        <returns><obj>aDate</obj></returns>
      </callseq>
      <desc>
<p/>
      Equivalent to <obj>ref</obj><tt>.newsg(Date::GREGORIAN)</tt>.
<p/>
      </desc>
    </method>
<p/>
        <method name="italy" ref="italy">
      <callseq>
        <obj>ref</obj>.italy <returns><obj>aDate</obj></returns>
      </callseq>
      <desc>
<p/>
      Equivalent to <obj>ref</obj><tt>.newsg(Date::ITALY)</tt>.
<p/>
      </desc>
    </method>
<p/>
        <method name="jd" ref="jd">
      <callseq>
        <obj>ref</obj>.jd <returns><obj>jd</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns the Julian day number for <obj>ref</obj>.
<p/>
      </desc>
    </method>
<p/>
        <method name="julian" ref="julian">
      <callseq>
        <obj>ref</obj>.julian <returns><obj>aDate</obj></returns>
      </callseq>
      <desc>
<p/>
      Equivalent to <obj>ref</obj><tt>.newsg(Date::JULIAN)</tt>.
<p/>
      </desc>
    </method>
<p/>
        <method name="leap?" ref="leap_qm">
      <callseq>
        <obj>ref</obj>.leap? <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Returns <const>true</const> if <obj>ref</obj> falls within a leap year.
<p/>
      </desc>
    </method>
<p/>
        <method name="mjd" ref="mjd">
      <callseq>
        <obj>ref</obj>.mjd <returns><obj>mjd</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns the Julian day number of <obj>ref</obj> converted to a modified Julian
      day number.
<p/>
      </desc>
    </method>
<p/>
        <method name="newsg" ref="newsg">
      <callseq>
        <obj>ref</obj>.newsg( <obj>sg</obj>=<const>Date::ITALY</const> )
        <returns><obj>aNewDate</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns a new <classname>Date</classname>.
<p/>
      </desc>
    </method>
<p/>
      <method name="next" ref="next">
      <callseq>
        <obj>ref</obj>.next <returns><obj>aNewDate</obj></returns>
      </callseq>
      <desc>
<p/>
    Synonym for <obj>ref</obj>.succ.
<p/>
      </desc>
    </method>
<p/>
        <method name="ns?" ref="ns_qm">
      <callseq>
        <obj>ref</obj>.ns? <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Returns <const>true</const> if <obj>ref</obj> falls in the period of New Style dates.
<p/>
      </desc>
    </method>
<p/>
        <method name="os?" ref="os_qm">
      <callseq>
        <obj>ref</obj>.os? <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Returns <const>true</const> if <obj>ref</obj> falls in the period of Old Style dates.
<p/>
      </desc>
    </method>
<p/>
        <method name="sg" ref="sg">
      <callseq>
        <obj>ref</obj>.sg <returns><obj>anInteger</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns the Julian day number of the start of New Style dates for
      <obj>ref</obj>.
<p/>
      </desc>
    </method>
<p/>
        <method name="step" ref="step">
      <callseq>
        <obj>ref</obj>.step( <obj>aDateLimit</obj>, <obj>step</obj> )
        <block>{| date | <blockbody>block</blockbody> }</block>
<p/>
        <returns><obj>ref</obj></returns>
      </callseq>
      <desc>
<p/>
      Invokes block with dates starting at <obj>ref</obj>,
      incrementing by <obj>step</obj> days, ending at the first date greater than
      <obj>aDateLimit</obj> (less than for a negative step).
<p/>
      </desc>
    </method>
<p/>
        <method name="succ" ref="succ">
      <callseq>
        <obj>ref</obj>.succ <returns><obj>aNewDate</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns the date of <obj>ref</obj> plus one day.
<p/>
      </desc>
    </method>
<p/>
        <method name="to_s" ref="to_s">
      <callseq>
        <obj>ref</obj>.to_s <returns><obj>aString</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns <tt>self</tt> as ``year-mon-mday.''
<p/>
      </desc>
    </method>
<p/>
        <method name="upto" ref="upto">
      <callseq>
        <obj>ref</obj>.upto( <obj>aDateMax</obj> )
        <block>{| date | <blockbody>block</blockbody> }</block>
<p/>
        <returns><obj>ref</obj></returns>
      </callseq>
      <desc>
<p/>
      Invokes block with dates from <obj>ref</obj> to <obj>aDateMax</obj>.
<p/>
      </desc>
    </method>
<p/>
</methods>
<p/>
</class>
<p/>
<library name="English">
<p/>
<codefragment>
<alltt><fullcode><![CDATA[      require "English"
      
      $OUTPUT_FIELD_SEPARATOR = ' -- '
      "waterbuffalo" =~ /buff/
      print $LOADED_FEATURES, $POSTMATCH, $PID, "\n"
      print $", $', $$, "\n"
]]></fullcode>
require<nbsp/>"English"
<p/>
$OUTPUT_FIELD_SEPARATOR<nbsp/>=<nbsp/>'<nbsp/>--<nbsp/>'
"waterbuffalo"<nbsp/>=~<nbsp/>/buff/
print<nbsp/>$LOADED_FEATURES,<nbsp/>$POSTMATCH,<nbsp/>$PID,<nbsp/>"\n"
print<nbsp/>$",<nbsp/>$',<nbsp/>$$,<nbsp/>"\n"
</alltt>
</codefragment>
<em>produces:</em>
<codefragment><alltt>
English.rb<nbsp/>--<nbsp/>alo<nbsp/>--<nbsp/>19685<nbsp/>--
English.rb<nbsp/>--<nbsp/>alo<nbsp/>--<nbsp/>19685<nbsp/>--
</alltt>
</codefragment>
<p/>
  Include the English library file in a Ruby script, and you can
  reference the global variables such as <var>$_</var> using less
  cryptic names, listed in the following table.  <table>
<p/>
    <toprule/><tr>
  <td><tt>$*</tt></td>
  <td>$ARGV</td>
  <td><tt>$"</tt></td>
  <td>$LOADED_FEATURES</td>
</tr>
<tr>
  <td><tt>$?</tt></td>
  <td>$CHILD_STATUS</td>
  <td><tt>$&amp;</tt></td>
  <td>$MATCH</td>
</tr>
<tr>
  <td><tt>$&lt;</tt></td>
  <td>$DEFAULT_INPUT</td>
  <td><tt>$.</tt></td>
  <td>$NR</td>
</tr>
<tr>
  <td><tt>$&gt;</tt></td>
  <td>$DEFAULT_OUTPUT</td>
  <td><tt>$,</tt></td>
  <td>$OFS</td>
</tr>
<tr>
  <td><tt>$!</tt></td>
  <td>$ERROR_INFO</td>
  <td><tt>$\</tt></td>
  <td>$ORS</td>
</tr>
<tr>
  <td><tt>$@</tt></td>
  <td>$ERROR_POSITION</td>
  <td><tt>$\</tt></td>
  <td>$OUTPUT_RECORD_SEPARATOR</td>
</tr>
<tr>
  <td><tt>$;</tt></td>
  <td>$FIELD_SEPARATOR</td>
  <td><tt>$,</tt></td>
  <td>$OUTPUT_FIELD_SEPARATOR</td>
</tr>
<tr>
  <td><tt>$;</tt></td>
  <td>$FS</td>
  <td><tt>$$</tt></td>
  <td>$PID</td>
</tr>
<tr>
  <td><tt>$=</tt></td>
  <td>$IGNORECASE</td>
  <td><tt>$'</tt></td>
  <td>$POSTMATCH</td>
</tr>
<tr>
  <td><tt>$.</tt></td>
  <td>$INPUT_LINE_NUMBER</td>
  <td><tt>$`</tt></td>
  <td>$PREMATCH</td>
</tr>
<tr>
  <td><tt>$/</tt></td>
  <td>$INPUT_RECORD_SEPARATOR</td>
  <td><tt>$$</tt></td>
  <td>$PROCESS_ID</td>
</tr>
<tr>
  <td><tt>$~</tt></td>
  <td>$LAST_MATCH_INFO</td>
  <td><tt>$0</tt></td>
  <td>$PROGRAM_NAME</td>
</tr>
<tr>
  <td><tt>$+</tt></td>
  <td>$LAST_PAREN_MATCH</td>
  <td><tt>$/</tt></td>
  <td>$RS</td>
</tr>
<tr>
  <td><tt>$_</tt></td>
  <td>$LAST_READ_LINE</td>
</tr>
<bottomrule/></table>
<p/>
</library>
<p/>
<class name="Find" type="module" ref="xref-000003">
<p/>
<codefragment>
<alltt><fullcode><![CDATA[      require "find"
      Find.find("/etc/passwd", "/var/spool/lp1", ".") do |f|
        Find.prune if f == "."
        puts f
      end
]]></fullcode>
require<nbsp/>"find"
Find.find("/etc/passwd",<nbsp/>"/var/spool/lp1",<nbsp/>".")<nbsp/>do<nbsp/>|f|
<nbsp/><nbsp/>Find.prune<nbsp/>if<nbsp/>f<nbsp/>==<nbsp/>"."
<nbsp/><nbsp/>puts<nbsp/>f
end
</alltt>
</codefragment>
<em>produces:</em>
<codefragment><alltt>
/etc/passwd
/var/spool/lp1
/var/spool/lp1/status
/var/spool/lp1/lock
/var/spool/lp1/.seq
</alltt>
</codefragment>
<p/>
  The <modulename>Find</modulename> module supports the top-down traversal of a set of
  file paths.
<p/>
  <methods type="class">
        <method name="find" ref="find">
      <callseq>
        <obj>ref</obj>.find( <optz><obj>aName</obj></optz> ) <block>{| aFileName | <blockbody>block</blockbody> }</block>
<p/>
      </callseq>
      <desc>
<p/>
      Calls the associated block with the name of every file and
      directory listed as arguments, then recursively on their
      subdirectories, and so on.
<p/>
      </desc>
    </method>
<p/>
        <method name="prune" ref="prune">
      <callseq>
        <obj>ref</obj>.prune
      </callseq>
      <desc>
<p/>
      Skips the current file or directory, restarting the
      loop with the next entry. If the current file is a directory,
      that directory will not be recursively entered.
      Meaningful only within the block associated with
      <mmm><front>Find</front><back>find</back></mmm>.
<p/>
      </desc>
    </method>
<p/>
  </methods>
<p/>
</class>
<p/>
<class name="File" super="IO" type="class" ref="xref-000004">
<p/>
<codefragment>
<fullcode><![CDATA[    require 'ftools'
    
    File.copy 'testfile', 'testfile1'
    File.compare 'testfile', 'testfile1'
]]></fullcode><rubycode>
<tr>
<td colspan="3"><tt>require<nbsp/>'ftools'</tt></td>
</tr>
<tr>
<td colspan="3"><tt></tt></td>
</tr>
<tr>
  <td><tt>File.copy<nbsp/>'testfile',<nbsp/>'testfile1'</tt></td>
  <td>&#187;</td>
  <td><tt>true</tt></td>
</tr>
<tr>
  <td><tt>File.compare<nbsp/>'testfile',<nbsp/>'testfile1'</tt></td>
  <td>&#187;</td>
  <td><tt>true</tt></td>
</tr>
</rubycode>
<p/>
</codefragment>
<p/>
  The <tt>FTools</tt> library adds several methods to the built-in
  <classname>File</classname> class. These methods are particularly useful to programs
  that move and copy files, such as installers.
<p/>
  <methods type="class">
        <method name="cmp" ref="cmp">
      <callseq>
        <obj>ref</obj>.cmp( <obj>name1</obj>, <obj>name2</obj>,
        <obj>verbose</obj>=<const>false</const> )
        <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Synonym for <ccm><file>file</file><front>File</front><back>compare</back><mref>compare</mref></ccm>.
<p/>
      </desc>
    </method>
<p/>
        <method name="compare" ref="compare">
      <callseq>
        <obj>ref</obj>.compare( <obj>name1</obj>, <obj>name2</obj>,
        <obj>verbose</obj>=<const>false</const> )
        <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Returns <const>true</const> only if the contents of files <obj>name1</obj>
      and <obj>name2</obj> are identical.
<p/>
      </desc>
    </method>
<p/>
        <method name="copy" ref="copy">
      <callseq>
        <obj>ref</obj>.copy( <obj>fromName</obj>, <obj>toName</obj>,
        <obj>verbose</obj>=<const>false</const> )
        <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Equivalent to calling <ccm><file>file</file><front>File</front><back>syscopy</back><mref>syscopy</mref></ccm>, but logs the attempt to 
      <var>$stderr</var> if <obj>verbose</obj> is not <const>false</const>.
<p/>
      </desc>
    </method>
<p/>
        <method name="cp" ref="cp">
      <callseq>
        <obj>ref</obj>.cp( <obj>fromName</obj>, <obj>toName</obj>,
        <obj>verbose</obj>=<const>false</const> )
        <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Synonym for <ccm><file>file</file><front>File</front><back>copy</back><mref>copy</mref></ccm>.
<p/>
      </desc>
    </method>
<p/>
        <method name="install" ref="install">
      <callseq>
        <obj>ref</obj>.install( <obj>fromName</obj>, <obj>toName</obj>,
        <obj>aMode</obj>=<tt>nil</tt>, <obj>verbose</obj>=<const>false</const> )
      </callseq>
      <desc>
<p/>
      Copies file <obj>fromName</obj> to file <obj>toName</obj> using
      <ccm><file>file</file><front>File</front><back>syscopy</back><mref>syscopy</mref></ccm>, unless <obj>toName</obj> already exists and has the
      same content as <obj>fromName</obj>. Sets the mode of the resulting file 
      to <obj>aMode</obj> unless <obj>aMode</obj> is <tt>nil</tt>.
<p/>
      </desc>
    </method>
<p/>
        <method name="makedirs" ref="makedirs">
      <callseq>
        <obj>ref</obj>.makedirs(
        <optz><obj>dirName</obj></optz> <opt>, <obj>aBoolean</obj></opt> )
      </callseq>
      <desc>
<p/>
      Creates the given directories, logging each attempt to
      <var>$stderr</var> if the last parameter is
      <const>true</const>. Creates any missing parent directories as
      required.
<p/>
      </desc>
    </method>
<p/>
        <method name="mkpath" ref="mkpath">
      <callseq>
        <obj>ref</obj>.mkpath(
        <optz><obj>dirName</obj></optz> <opt>, <obj>aBoolean</obj></opt> )
      </callseq>
      <desc>
<p/>
      Synonym for <ccm><file>file</file><front>File</front><back>makedirs</back><mref>makedirs</mref></ccm>.
<p/>
      </desc>
    </method>
<p/>
        <method name="move" ref="move">
      <callseq>
        <obj>ref</obj>.move( <obj>fromName</obj>, <obj>toName</obj>,
        <obj>verbose</obj>=<const>false</const> )
        <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Effectively renames <obj>fromName</obj> to <obj>toName</obj>, logging to
      <var>$stderr</var> if <obj>verbose</obj> is not <const>false</const>.
<p/>
      </desc>
    </method>
<p/>
        <method name="mv" ref="mv">
      <callseq>
        <obj>ref</obj>.mv( <obj>fromName</obj>, <obj>toName</obj>,
        <obj>verbose</obj>=<const>false</const> )
        <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Synonym for <ccm><file>file</file><front>File</front><back>move</back><mref>move</mref></ccm>.
<p/>
      </desc>
    </method>
<p/>
        <method name="rm_f" ref="rm_f">
      <callseq>
        <obj>ref</obj>.rm_f(
        <optz><obj>fileName</obj></optz> <opt>, <obj>aBoolean</obj></opt> )
        <returns><obj>anInteger</obj></returns>
      </callseq>
      <desc>
<p/>
      Synonym for <ccm><file>file</file><front>File</front><back>safe_unlink</back><mref>safe_unlink</mref></ccm> (the name refers
      to the Unix <tt>rm<nbsp/>-f</tt> command).
<p/>
      </desc>
    </method>
<p/>
        <method name="safe_unlink" ref="safe_unlink">
      <callseq>
        <obj>ref</obj>.safe_unlink(
        <optz><obj>fileName</obj></optz> <opt>, <obj>aBoolean</obj></opt> )
        <returns><obj>anInteger</obj> or <tt>nil</tt></returns>
      </callseq>
      <desc>
<p/>
      Unlinks (deletes) the given files, logging to <var>$stderr</var> if
      the last parameter is <const>true</const>. The method attempts to make all files
      writable before unlinking them, so no errors will occur deleting 
      read-only files. Returns the number of files deleted, or <tt>nil</tt>
      on error.
<p/>
      </desc>
    </method>
<p/>
        <method name="syscopy" ref="syscopy">
      <callseq>
        <obj>ref</obj>.syscopy( <obj>fromName</obj>, <obj>toName</obj> )
        <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Efficiently copies the file named <obj>fromName</obj> to
      <obj>toName</obj>. If <obj>toName</obj> names a directory, the destination 
      will be a file in that directory with the same basename as
      <obj>fromName</obj>. After the copy, the file mode of <obj>toName</obj>
      will be the same as that of <obj>fromName</obj>. Returns <const>true</const> 
      on success.
<p/>
      </desc>
    </method>
<p/>
  </methods>
<p/>
</class>
<p/>
<class name="GetoptLong" super="Object" type="class" ref="xref-000005">      
<p/>
<codefragment>
<alltt><fullcode><![CDATA[      # Call using "ruby example.rb --size 10k -v -q a.txt b.doc"
      
      require 'getoptlong'
!-    # Fake out an initial command line
!-    ARGV.clear.push  *%w(--size 10k -v -q a.txt b.doc)

      # specify the options we accept and initialize
      # the option parser
      
      opts = GetoptLong.new(
        [ "--size",    "-s",            GetoptLong::REQUIRED_ARGUMENT ],
        [ "--verbose", "-v",            GetoptLong::NO_ARGUMENT ],
        [ "--query",   "-q",            GetoptLong::NO_ARGUMENT ],
        [ "--check",   "--valid", "-c", GetoptLong::NO_ARGUMENT ]
      )

      # process the parsed options
      
      opts.each do |opt, arg|
        puts "Option: #{opt}, arg #{arg.inspect}"
      end

      puts "Remaining args: #{ARGV.join(', ')}"
]]></fullcode>
#<nbsp/>Call<nbsp/>using<nbsp/>"ruby<nbsp/>example.rb<nbsp/>--size<nbsp/>10k<nbsp/>-v<nbsp/>-q<nbsp/>a.txt<nbsp/>b.doc"
<p/>
require<nbsp/>'getoptlong'
<p/>
#<nbsp/>specify<nbsp/>the<nbsp/>options<nbsp/>we<nbsp/>accept<nbsp/>and<nbsp/>initialize
#<nbsp/>the<nbsp/>option<nbsp/>parser
<p/>
opts<nbsp/>=<nbsp/>GetoptLong.new(
<nbsp/><nbsp/>[<nbsp/>"--size",<nbsp/><nbsp/><nbsp/><nbsp/>"-s",<nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/>GetoptLong::REQUIRED_ARGUMENT<nbsp/>],
<nbsp/><nbsp/>[<nbsp/>"--verbose",<nbsp/>"-v",<nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/>GetoptLong::NO_ARGUMENT<nbsp/>],
<nbsp/><nbsp/>[<nbsp/>"--query",<nbsp/><nbsp/><nbsp/>"-q",<nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/>GetoptLong::NO_ARGUMENT<nbsp/>],
<nbsp/><nbsp/>[<nbsp/>"--check",<nbsp/><nbsp/><nbsp/>"--valid",<nbsp/>"-c",<nbsp/>GetoptLong::NO_ARGUMENT<nbsp/>]
)
<p/>
#<nbsp/>process<nbsp/>the<nbsp/>parsed<nbsp/>options
<p/>
opts.each<nbsp/>do<nbsp/>|opt,<nbsp/>arg|
<nbsp/><nbsp/>puts<nbsp/>"Option:<nbsp/>#{opt},<nbsp/>arg<nbsp/>#{arg.inspect}"
end
<p/>
puts<nbsp/>"Remaining<nbsp/>args:<nbsp/>#{ARGV.join(',<nbsp/>')}"
</alltt>
</codefragment>
<em>produces:</em>
<codefragment><alltt>
Option:<nbsp/>--size,<nbsp/>arg<nbsp/>"10k"
Option:<nbsp/>--verbose,<nbsp/>arg<nbsp/>""
Option:<nbsp/>--query,<nbsp/>arg<nbsp/>""
Remaining<nbsp/>args:<nbsp/>a.txt,<nbsp/>b.doc
</alltt>
</codefragment>
<p/>
  Class <classname>GetoptLong</classname> supports GNU-style command-line option parsing.
  Options may be a minus sign (`-') followed by a single character, or
  two minus signs (`--') followed by a name (a long option). Long
  options may be abbreviated to their shortest unambiguous lengths.
<p/>
  A single internal option may have multiple external representations.
  For example, the option to control verbose output could be any of
  <tt>-v</tt>, <tt>--verbose</tt>, or <tt>--details</tt>.  Some options may
  also take an associated value.
<p/>
  Each internal option is passed to <classname>GetoptLong</classname> as an array,
  containing strings representing the option's external forms and a
  flag. The flag (<tt>NO_ARGUMENT</tt>, <tt>REQUIRED_ARGUMENT</tt>, or
  <tt>OPTIONAL_ARGUMENT</tt>) specifies how <classname>GetoptLong</classname> is to
  associate an argument with the option.
<p/>
  If the environment variable
  <tt>POSIXLY_CORRECT</tt> is set, all options
  must precede nonoptions on the command line. Otherwise, the default
  behavior of <classname>GetoptLong</classname> is to reorganize the command line to put
  the options at the front.  This behavior may be changed by setting
  <cim><front>GetoptLong</front><back>ordering=</back></cim> to one of the constants
  <tt>PERMUTE</tt>, <tt>REQUIRE_ORDER</tt>, or <tt>RETURN_IN_ORDER</tt>.
  <tt>POSIXLY_CORRECT</tt> may not be overridden.
<p/>
  <constants>
<th>
  <td><em><b>Per-option constants</b></em></td>
</th>
<p/>
    <constant>
       <constname>NO_ARGUMENT</constname>
       <constval></constval>
       <constdesc>Flags an option that takes no argument.</constdesc>
     </constant>
<p/>
    <constant>
       <constname>OPTIONAL_ARGUMENT</constname>
       <constval></constval>
       <constdesc>A nonoption following this option
      will be used as this option's argument.</constdesc>
     </constant>
<p/>
    <constant>
       <constname>REQUIRED_ARGUMENT</constname>
       <constval></constval>
       <constdesc>This option must be followed by an
      argument.</constdesc>
     </constant>
<p/>
    <toprule/><tr>
  <td><em><b>Overall constants</b></em></td>
</tr>
<p/>
    <constant>
       <constname>PERMUTE</constname>
       <constval></constval>
       <constdesc>Options and their arguments will be shuffled
      to the front of the command line.</constdesc>
     </constant>
<p/>
    <constant>
       <constname>REQUIRE_ORDER</constname>
       <constval></constval>
       <constdesc>Options and their arguments must
      appear at the start of the command line. The first nonoption
      terminates option processing.</constdesc>
     </constant>
<p/>
    <constant>
       <constname>RETURN_IN_ORDER</constname>
       <constval></constval>
       <constdesc>Return options in the order in
      which they occur on the command line.</constdesc>
     </constant>
<p/>
    <bottomrule/></constants>
<p/>
  <methods type="class">
        <method name="new" ref="new">
      <callseq>
                GetoptLong.new( <optz><obj>options</obj></optz> ) <returns><obj>ref</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns a new option parser. Any <obj>options</obj> are passed to
      <obj>ref</obj>.<meth>set_options</meth>.
<p/>
      </desc>
    </method>
<p/>
  </methods>
<p/>
  <methods type="instance">
        <method name="each" ref="each">
      <callseq>
        <obj>ref</obj>.each <block>{| anOption, anArgument | <blockbody>block</blockbody> }</block>
<p/>
      </callseq>
      <desc>
<p/>
      Loops calling <cim><front>GetoptLong</front><back>get</back></cim>, passing the returned option
      and argument to the associated block. The loop ends when <tt>get</tt> 
      returns <tt>nil</tt> for <obj>anOption</obj>.
<p/>
      </desc>
    </method>
<p/>
        <method name="error?" ref="error_qm">
      <callseq>
        <obj>ref</obj>.error?
        <returns><obj>anException</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns an <classname>Exception</classname> object documenting any error that has
      occurred, or <tt>nil</tt> if there has not been an error.
<p/>
      </desc>
    </method>
<p/>
        <method name="error_message" ref="error_message">
      <callseq>
        <obj>ref</obj>.error_message
        <returns><obj>aString</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns the text of the last error message.    
      </desc>
    </method>
<p/>
        <method name="get" ref="get">
      <callseq>
        <obj>ref</obj>.get <returns>[ <obj>anOption</obj>,
          <obj>anArgument</obj> ]</returns>
      </callseq>
      <desc>
<p/>
      Returns the next option, along with any associated argument. If
      there is no argument, <tt>nil</tt> is returned for
      <obj>anArgument</obj>. If there are no remaining unprocessed options,
      or if there is an error in option processing and <meth>quiet</meth>
      has been set, <tt>nil</tt> is returned for
      <obj>anOption</obj>. Otherwise,
      if there is an error, a message is written to <var>$stderr</var> and 
      an exception (a subclass of <exception>StandardError</exception>) is raised.
<p/>
      The option string returned is the first option that was given in 
      the corresponding array passed to <meth>set_options</meth>.
<p/>
      </desc>
    </method>
<p/>
        <method name="get_option" ref="get_option">
      <callseq>
        <obj>ref</obj>.get_option <returns>[ <obj>anOption</obj>,
          <obj>anArgument</obj> ]</returns>
      </callseq>
      <desc>
<p/>
      Synonym for <cim><front>GetoptLong</front><back>get</back></cim>.
<p/>
      </desc>
    </method>
<p/>
        <method name="ordering" ref="ordering">
      <callseq>
        <obj>ref</obj>.ordering <returns><obj>aFixnum</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns the current ordering.
<p/>
      </desc>
    </method>
<p/>
        <method name="ordering=" ref="ordering_eq">
      <callseq>
        <obj>ref</obj>.ordering = <obj>aFixnum</obj>
      </callseq>
      <desc>
<p/>
      Sets the ordering to one of <tt>PERMUTE</tt>, <tt>REQUIRE_ORDER</tt>,
      or <tt>RETURN_IN_ORDER</tt>. Quietly ignored if the environment
      variable <tt>POSIXLY_CORRECT</tt> is set. Ordering may not be
      changed once option processing has been started.
<p/>
      </desc>
    </method>
<p/>
        <method name="quiet" ref="quiet">
      <callseq>
        <obj>ref</obj>.quiet <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Returns the current value of the <tt>quiet</tt> attribute.
<p/>
      </desc>
    </method>
<p/>
        <method name="quiet=" ref="quiet_eq">
      <callseq>
        <obj>ref</obj>.quiet = <const>true</const> or <const>false</const></callseq>
      <desc>
<p/>
      Sets the current value of the <tt>quiet</tt> attribute. If
      <const>false</const>, any errors encountered are reported to
      <var>$stderr</var>.
<p/>
      </desc>
    </method>
<p/>
        <method name="quiet?" ref="quiet_qm">
      <callseq>
        <obj>ref</obj>.quiet? <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Synonym for <cim><front>GetoptLong</front><back>quiet</back></cim>.
<p/>
      </desc>
    </method>
<p/>
        <method name="set_options" ref="set_options">
      <callseq>
        <obj>ref</obj>.set_options(
        <optz><obj>anOptArray</obj></optz> ) <returns><obj>ref</obj></returns>
      </callseq>
      <desc>
<p/>
      Each parameter is an array specifying a single internal option.
      The array contains one or more strings specifying the external
      form(s) of the option, and one of the flags <tt>NO_ARGUMENT</tt>,
      <tt>OPTIONAL_ARGUMENT</tt>, or <tt>REQUIRED_ARGUMENT</tt>. See the
      sample code on page 448 for examples of use.
<p/>
      </desc>
    </method>
<p/>
        <method name="terminate" ref="terminate">
      <callseq>
        <obj>ref</obj>.terminate <returns><obj>ref</obj></returns>
      </callseq>
      <desc>
<p/>
      Terminates option processing. Any remaining arguments are
      written back to <var>ARGV</var>.  This may be called from within a
      <cim><front>GetoptLong</front><back>each</back></cim> or on its own.    For example, calling the
      following program using ``<tt>ruby example.rb --size 10k -v
        -term -q a.txt b.doc</tt>'' will leave the <tt>-q</tt> and filenames
      in <var>ARGV</var>.
<p/>
<codefragment>
<alltt><fullcode><![CDATA[        require 'getoptlong'
!-      # Fake out an initial command line
!-      ARGV.clear.push  *%w(--size 10k -v -t -q a.txt b.doc)

        opts = GetoptLong.new(
          [ "--size",    "-s",            GetoptLong::REQUIRED_ARGUMENT ],
          [ "--verbose", "-v",            GetoptLong::NO_ARGUMENT ],
          [ "--term",    "-t",            GetoptLong::NO_ARGUMENT ],
          [ "--query",   "-q",            GetoptLong::NO_ARGUMENT ],
          [ "--check",   "--valid", "-c", GetoptLong::NO_ARGUMENT ]
          )

        opts.each do |opt, arg|
          puts "Option: #{opt}, arg #{arg.inspect}"
          opts.terminate if (opt == '--term') 
        end

        puts "Remaining args: #{ARGV.join(', ')}"
]]></fullcode>
require<nbsp/>'getoptlong'
<p/>
opts<nbsp/>=<nbsp/>GetoptLong.new(
<nbsp/><nbsp/>[<nbsp/>"--size",<nbsp/><nbsp/><nbsp/><nbsp/>"-s",<nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/>GetoptLong::REQUIRED_ARGUMENT<nbsp/>],
<nbsp/><nbsp/>[<nbsp/>"--verbose",<nbsp/>"-v",<nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/>GetoptLong::NO_ARGUMENT<nbsp/>],
<nbsp/><nbsp/>[<nbsp/>"--term",<nbsp/><nbsp/><nbsp/><nbsp/>"-t",<nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/>GetoptLong::NO_ARGUMENT<nbsp/>],
<nbsp/><nbsp/>[<nbsp/>"--query",<nbsp/><nbsp/><nbsp/>"-q",<nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/>GetoptLong::NO_ARGUMENT<nbsp/>],
<nbsp/><nbsp/>[<nbsp/>"--check",<nbsp/><nbsp/><nbsp/>"--valid",<nbsp/>"-c",<nbsp/>GetoptLong::NO_ARGUMENT<nbsp/>]
<nbsp/><nbsp/>)
<p/>
opts.each<nbsp/>do<nbsp/>|opt,<nbsp/>arg|
<nbsp/><nbsp/>puts<nbsp/>"Option:<nbsp/>#{opt},<nbsp/>arg<nbsp/>#{arg.inspect}"
<nbsp/><nbsp/>opts.terminate<nbsp/>if<nbsp/>(opt<nbsp/>==<nbsp/>'--term')
end
<p/>
puts<nbsp/>"Remaining<nbsp/>args:<nbsp/>#{ARGV.join(',<nbsp/>')}"
</alltt>
</codefragment>
<em>produces:</em>
<codefragment><alltt>
Option:<nbsp/>--size,<nbsp/>arg<nbsp/>"10k"
Option:<nbsp/>--verbose,<nbsp/>arg<nbsp/>""
Option:<nbsp/>--term,<nbsp/>arg<nbsp/>""
Remaining<nbsp/>args:<nbsp/>-q,<nbsp/>a.txt,<nbsp/>b.doc
</alltt>
</codefragment>
<p/>
      </desc>
    </method>
<p/>
        <method name="terminated?" ref="terminated_qm">
      <callseq>
        <obj>ref</obj>.terminated?
        <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Returns <const>true</const> if option processing has been terminated.
<p/>
      </desc>
    </method>
<p/>
  </methods>
<p/>
</class>
<p/>
<class name="mkmf" type="module" ref="xref-000006">
<p/>
  The <classname>mkmf</classname> library is used by Ruby extension modules to help
  create <tt>Makefiles</tt>.  When writing an extension, you create a
  program named ``<tt>extconf.rb</tt>'', which may be as simple as:
<p/>
<codefragment>
<alltt><fullcode><![CDATA[    require 'mkmf'
    create_makefile("Test")
]]></fullcode>
require<nbsp/>'mkmf'
create_makefile("Test")
</alltt>
</codefragment>
<p/>
  When run, this script will produce a <tt>Makefile</tt> suited to the
  target platform.  <classname>mkmf</classname> contains several methods you can use
  to find libraries and include files and to set compiler flags.
<p/>
  For more information on creating extension modules, see Chapter
  17, which begins on page 169.
<p/>
<constants>
<tr>
  <td><constant>
       <constname>PLATFORM</constname>
       <constval>varies</constval>
       <constdesc>A constant string that describes the
      platform on which Ruby is running, such as ``mswin32'' or
      ``i686-linux.''</constdesc>
     </constant>
<p/>
    <constant>
       <constname>$CFLAGS</constname>
       <constval></constval>
       <constdesc>Global variable for compiler flags.</constdesc>
     </constant>
<p/>
    <constant>
       <constname>$LDFLAGS</constname>
       <constval></constval>
       <constdesc>Global variable for linker flags.</constdesc>
     </constant>
</td>
</tr>
</constants>
<p/>
  <methods type="instance">
        <method name="create_makefile" ref="create_makefile">
      <callseq>
        create_makefile( <obj>target</obj> )
      </callseq>
      <desc>
<p/>
      Creates a <tt>Makefile</tt> for an extension named <em>target</em>.
      If this method is not called, no <tt>Makefile</tt> is created.
<p/>
      </desc>
    </method>
<p/>
        <method name="dir_config" ref="dir_config">
      <callseq>
        dir_config( <obj>name</obj> )
      </callseq>
      <desc>
<p/>
      Looks for directory configuration options for <em>name</em> given
      as arguments to this program or to the original build of Ruby.
      These arguments may be one of:
<p/>
      <table>
<tr>
  <td><tt>--with-</tt><em>name</em><tt>-dir</tt>=<em>directory</em></td>
</tr>
<tr>
  <td><tt>--with-</tt><em>name</em><tt>-include</tt>=<em>directory</em></td>
</tr>
<tr>
  <td><tt>--with-</tt><em>name</em><tt>-lib</tt>=<em>directory</em></td>
</tr>
</table>
<p/>
      The given directories will be added to the appropriate search
      paths (include or link) in the <tt>Makefile</tt>.
<p/>
      </desc>
    </method>
<p/>
        <method name="find_library" ref="find_library">
      <callseq>
        find_library( <obj>name</obj>,
        <obj>function</obj>, <optn><obj>path</obj></optn> ) 
        <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Same as <meth>have_library</meth>, but will also search in the given
      directory paths.
<p/>
      </desc>
    </method>
<p/>
        <method name="have_func" ref="have_func">
      <callseq>
        have_func( <obj>function</obj> ) 
        <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      If the named
      function exists in the standard compile environment,
      adds the directive -DHAVE_<em>FUNCTION</em>
      to the compile command in the <tt>Makefile</tt> and returns <const>true</const>.
<p/>
      </desc>
    </method>
<p/>
        <method name="have_header" ref="have_header">
      <callseq>
        have_header( <obj>header</obj> )
        <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      If the given header file can be found in the
      standard search path, adds the directive -DHAVE_<em>HEADER</em> 
      to the compile command in the <tt>Makefile</tt>  and returns <const>true</const>.
<p/>
      </desc>
    </method>
<p/>
        <method name="have_library" ref="have_library">
      <callseq>
        have_library( <obj>library</obj>, 
        <obj>function</obj> ) <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      If the given function exists in the named library, which must exist in
      the standard search path or in a directory added with
      <meth>dir_config</meth>, adds the library to the link command
      in the <tt>Makefile</tt>  and returns <const>true</const>.
<p/>
      </desc>
    </method>
<p/>
  </methods>
<p/>
</class>
<p/>
<class name="ParseDate" type="module" ref="xref-000007">
<p/>
  The <modulename>ParseDate</modulename> module defines a single method,
  <mmm><front>ParseDate</front><back>parsedate</back></mmm>, which converts a date and/or time string
  into its constituents. It uses heuristics that handle a wide
  variety of date and time formats, including a subset of ISO<nbsp/>8601,
  Unix <tt>ctime</tt>, and most common written variants. The following table shows
  some examples.<nbsp/>
<p/>
  <table>
<th>
<td colspan="2"><b>StringGuess?</b></td>
  <td><b>yy</b></td>
  <td><b>mm</b></td>
  <td><b>dd</b></td>
  <td><b>hh</b></td>
  <td><b>min</b></td>
  <td><b>sec</b></td>
  <td><b>zone</b></td>
  <td><b>wd</b></td>
</th>
<tr>
  <td>1999-09-05 23:55:21+0900</td>
  <td>F</td>
  <td>1999</td>
  <td>9</td>
  <td>5</td>
  <td>23</td>
  <td>55</td>
  <td>21</td>
  <td>+0900</td>
  <td>--</td>
</tr>
<tr>
  <td>1983-12-25</td>
  <td>F</td>
  <td>1983</td>
  <td>12</td>
  <td>25</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
</tr>
<tr>
  <td>1965-11-10 T13:45</td>
  <td>F</td>
  <td>1965</td>
  <td>11</td>
  <td>10</td>
  <td>13</td>
  <td>45</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
</tr>
<tr>
  <td>10/9/75 1:30pm</td>
  <td>F</td>
  <td>75</td>
  <td>10</td>
  <td>9</td>
  <td>13</td>
  <td>30</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
</tr>
<tr>
  <td>10/9/75 1:30pm</td>
  <td>T</td>
  <td>1975</td>
  <td>10</td>
  <td>9</td>
  <td>13</td>
  <td>30</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
</tr>
<tr>
  <td>Mon Feb 28 17:15:49 CST 2000</td>
  <td>F</td>
  <td>2000</td>
  <td>2</td>
  <td>28</td>
  <td>17</td>
  <td>15</td>
  <td>49</td>
  <td>CST</td>
  <td>1</td>
</tr>
<tr>
  <td>Tue, 02-Mar-99 11:20:32 GMT</td>
  <td>F</td>
  <td>99</td>
  <td>3</td>
  <td>2</td>
  <td>11</td>
  <td>20</td>
  <td>32</td>
  <td>GMT</td>
  <td>2</td>
</tr>
<tr>
  <td>Tue, 02-Mar-99 11:20:32 GMT</td>
  <td>T</td>
  <td>1999</td>
  <td>3</td>
  <td>2</td>
  <td>11</td>
  <td>20</td>
  <td>32</td>
  <td>GMT</td>
  <td>2</td>
</tr>
<tr>
  <td>12-January-1990, 04:00 WET</td>
  <td>F</td>
  <td>1990</td>
  <td>1</td>
  <td>12</td>
  <td>4</td>
  <td>0</td>
  <td>--</td>
  <td>WET</td>
  <td>--</td>
</tr>
<tr>
  <td>4/3/99</td>
  <td>F</td>
  <td>99</td>
  <td>4</td>
  <td>3</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
</tr>
<tr>
  <td>4/3/99</td>
  <td>T</td>
  <td>1999</td>
  <td>4</td>
  <td>3</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
</tr>
<tr>
  <td>10th February, 1976</td>
  <td>F</td>
  <td>1976</td>
  <td>2</td>
  <td>10</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
</tr>
<tr>
  <td>March 1st, 84</td>
  <td>T</td>
  <td>1984</td>
  <td>3</td>
  <td>1</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
</tr>
<tr>
  <td>Friday</td>
  <td>F</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
  <td>--</td>
  <td>5</td>
</tr>
<bottomrule/></table>
<p/>
  <methods type="class">
        <method name="parsedate" ref="parsedate">
      <callseq>
        <obj>ref</obj>.parsedate( <obj>aString</obj>, <obj>guessYear</obj>=<const>false</const> )<br/><returns>[ <obj>year</obj>, <obj>mon</obj>, <obj>mday</obj>,
          <obj>hour</obj>, <obj>min</obj>, <obj>sec</obj>, <obj>zone</obj>, <obj>wday</obj>
          ]</returns>
      </callseq>
      <desc>
<p/>
      Parses a string containing a date and/or a time, returning an
      array of <classname>Fixnum</classname> objects containing the various components.
      <tt>nil</tt> is returned for fields that cannot be parsed from
      <obj>aString</obj>. If the result contains a year that is less than
      100 and <obj>guessYear</obj> is true, <meth>parsedate</meth> will return
      a year value equal to <obj>year</obj> plus 2000 if <obj>year</obj> is less
      than 69, <obj>year</obj> plus 1900 otherwise.
<p/>
      </desc>
    </method>
<p/>
  </methods>
<p/>
</class>
<p/>
<library name="profile">
<p/>
  The <tt>profile</tt> library prints to <var>$stderr</var> a summary
  of the number of calls to, and the time spent in, each method in a
  Ruby program. The output is sorted by the total time spent in each
  method. Profiling can be enabled from the command line using the
  <cmdopt>-r</cmdopt><tt>profile</tt> option, or from within a source program by 
  requiring the <tt>profile</tt> module.    
<p/>
<codefragment>
<alltt><fullcode><![CDATA[    require 'profile'
    def ackerman(m, n)
      if m == 0 then  n+1
      elsif n == 0 and m > 0 then ackerman(m-1, 1)
      else ackerman(m-1, ackerman(m, n-1))
      end
    end
    ackerman(3,3)
]]></fullcode>
require<nbsp/>'profile'
def<nbsp/>ackerman(m,<nbsp/>n)
<nbsp/><nbsp/>if<nbsp/>m<nbsp/>==<nbsp/>0<nbsp/>then<nbsp/><nbsp/>n+1
<nbsp/><nbsp/>elsif<nbsp/>n<nbsp/>==<nbsp/>0<nbsp/>and<nbsp/>m<nbsp/>&gt;<nbsp/>0<nbsp/>then<nbsp/>ackerman(m-1,<nbsp/>1)
<nbsp/><nbsp/>else<nbsp/>ackerman(m-1,<nbsp/>ackerman(m,<nbsp/>n-1))
<nbsp/><nbsp/>end
end
ackerman(3,3)
</alltt>
</codefragment>
<p/>
<em>produces:</em>
<verbatim>
 time   seconds   seconds    calls  ms/call  ms/call  name
 74.04     2.51      2.51     2432     1.03    42.68  Object#ackerman
 14.16     2.99      0.48     3676     0.13     0.13  Fixnum#==
  9.14     3.30      0.31     2431     0.13     0.13  Fixnum#-
  2.36     3.38      0.08     1188     0.07     0.07  Fixnum#+
  0.29     3.39      0.01       57     0.18     0.18  Fixnum#&gt;
  0.00     3.39      0.00        1     0.00     0.00  Module#method_added
  0.00     3.39      0.00        1     0.00  3390.00  #toplevel
</verbatim>
</library>
<p/>
<class name="PStore" super="Object" type="class" ref="xref-000008">    
<p/>
    The <classname>PStore</classname> class provides transactional, file-based
    persistent storage of Ruby objects.  The following example stores two
    hierarchies in a PStore. The first, identified by the key
    ``<tt>names</tt>'', is an array of Strings. The second, identified by
    ``<tt>tree</tt>'', is a simple binary tree.
<p/>
<codefragment>
<alltt><fullcode><![CDATA[       require "pstore"

       class T
         def initialize(val, left=nil, right=nil)
           @val, @left, @right = val, left, right
         end
         def to_a
           [ @val, @left.to_a, @right.to_a ]
         end
       end

       store = PStore.new("/tmp/store")
       store.transaction do
          store['names'] = [ 'Douglas', 'Barenberg', 'Meyer' ]
          store['tree']  = T.new('top', 
                             T.new('A', T.new('B')),
                             T.new('C', T.new('D', nil, T.new('E'))))
       end

       # now read it back in

       store.transaction do 
          puts "Roots: #{store.roots.join(', ')}"
          puts store['names'].join(', ')
          puts store['tree'].to_a.inspect
       end
]]></fullcode>
require<nbsp/>"pstore"
<p/>
class<nbsp/>T
<nbsp/><nbsp/>def<nbsp/>initialize(val,<nbsp/>left=nil,<nbsp/>right=nil)
<nbsp/><nbsp/><nbsp/><nbsp/>@val,<nbsp/>@left,<nbsp/>@right<nbsp/>=<nbsp/>val,<nbsp/>left,<nbsp/>right
<nbsp/><nbsp/>end
<nbsp/><nbsp/>def<nbsp/>to_a
<nbsp/><nbsp/><nbsp/><nbsp/>[<nbsp/>@val,<nbsp/>@left.to_a,<nbsp/>@right.to_a<nbsp/>]
<nbsp/><nbsp/>end
end
<p/>
store<nbsp/>=<nbsp/>PStore.new("/tmp/store")
store.transaction<nbsp/>do
<nbsp/><nbsp/><nbsp/>store['names']<nbsp/>=<nbsp/>[<nbsp/>'Douglas',<nbsp/>'Barenberg',<nbsp/>'Meyer'<nbsp/>]
<nbsp/><nbsp/><nbsp/>store['tree']<nbsp/><nbsp/>=<nbsp/>T.new('top',
<nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/>T.new('A',<nbsp/>T.new('B')),
<nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/>T.new('C',<nbsp/>T.new('D',<nbsp/>nil,<nbsp/>T.new('E'))))
end
<p/>
#<nbsp/>now<nbsp/>read<nbsp/>it<nbsp/>back<nbsp/>in
<p/>
store.transaction<nbsp/>do
<nbsp/><nbsp/><nbsp/>puts<nbsp/>"Roots:<nbsp/>#{store.roots.join(',<nbsp/>')}"
<nbsp/><nbsp/><nbsp/>puts<nbsp/>store['names'].join(',<nbsp/>')
<nbsp/><nbsp/><nbsp/>puts<nbsp/>store['tree'].to_a.inspect
end
</alltt>
</codefragment>
<em>produces:</em>
<codefragment><alltt>
Roots:<nbsp/>names,<nbsp/>tree
Douglas,<nbsp/>Barenberg,<nbsp/>Meyer
["top",<nbsp/>["A",<nbsp/>["B",<nbsp/>[],<nbsp/>[]],<nbsp/>[]],<nbsp/>["C",<nbsp/>["D",<nbsp/>[],<nbsp/>["E",<nbsp/>[],<nbsp/>[]]],<nbsp/>[]]]
</alltt>
</codefragment>
<p/>
  Each <classname>PStore</classname> can store several
  object hierarchies. Each hierarchy has a root, identified by a key
  (often a string). At the start of a <classname>PStore</classname> transaction, these
  hierarchies are read from a disk file and made available to the Ruby
  program. At the end of the transaction, the hierarchies are written
  back to the file. Any changes made to objects in these hierarchies
  are therefore saved on disk, to be read at the start of the next
  transaction that uses that file.
<p/>
  In normal use, a <classname>PStore</classname> object is created and then is used one or
  more times to control a transaction. Within the body of the
  transaction, any object hierarchies that had previously been saved
  are made available, and any changes to object hierarchies, and any
  new hierarchies, are written back to the file at the end.
<p/>
  <methods type="class">
        <method name="new" ref="new">
      <callseq>
        PStore.new( <obj>aFilename</obj> )
        <returns><obj>aPStore</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns a new <classname>PStore</classname> object associated with the given
      file. If the file exists, its contents must have been previously 
      written by <classname>PStore</classname>.
<p/>
      </desc>
    </method>
<p/>
  </methods>
<p/>
  <methods type="instance">
        <method name="[ ]" ref="_ob_cb">
      <callseq>
        <obj>ref</obj>[ <obj>anObject</obj> ] <returns><obj>anOtherObject</obj></returns>
      </callseq>
      <desc>
<p/>
      Root Access---Returns the root of an object hierarchy identified
      by <obj>anObject</obj>. An exception is raised if <obj>anObject</obj> does 
      not identify a root.
<p/>
      </desc>
    </method>
<p/>
        <method name="[ ]=" ref="_ob_cb_eq">
      <callseq>
        <obj>ref</obj>[ <obj>anObject</obj> ] =
        <obj>anOtherObject</obj>
        <returns><obj>anOtherObject</obj></returns>
      </callseq>
      <desc>
<p/>
      Root Creation---Sets <obj>anOtherObject</obj> as the base of the object 
      hierarchy to be identified using <obj>anObject</obj>.
<p/>
      </desc>
    </method>
<p/>
        <method name="abort" ref="abort">
      <callseq>
        <obj>ref</obj>.abort
      </callseq>
      <desc>
<p/>
      Terminates this transaction, losing any changes made to the
      object hierarchies.
<p/>
      </desc>
    </method>
<p/>
        <method name="commit" ref="commit">
      <callseq>
        <obj>ref</obj>.commit
      </callseq>
      <desc>
<p/>
      Terminates the current transaction, saving the object hierarchies 
      into the store's file.
<p/>
      </desc>
    </method>
<p/>
        <method name="path" ref="path">
      <callseq>
        <obj>ref</obj>.path <returns><obj>aString</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns the name of the file associated with this store.
<p/>
      </desc>
    </method>
<p/>
        <method name="root?" ref="root_qm">
      <callseq>
        <obj>ref</obj>.root?( <obj>anObject</obj> )
        <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Returns <const>true</const> if <obj>anObject</obj> is the key of a root in
      this store.
<p/>
      </desc>
    </method>
<p/>
        <method name="roots" ref="roots">
      <callseq>
        <obj>ref</obj>.roots <returns><obj>anArray</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns an array containing the keys of the root objects
      available in this store.
<p/>
      </desc>
    </method>
<p/>
        <method name="transaction" ref="transaction">
      <callseq>
        <obj>ref</obj>.transaction <block>{| <obj>ref</obj> | <blockbody>block</blockbody> }</block>
<p/>
        <returns><obj>anObject</obj></returns>
      </callseq>
      <desc>
<p/>
      If the file associated with <obj>ref</obj> exists, reads in the object
      hierarchies from it. It then executes the associated block, passing
      in <obj>ref</obj>. The block may use this parameter to access the roots
      of the hierarchies and hence access the persistent objects. If
      the block calls <cim><front>PStore</front><back>abort</back></cim>, or if it raises an exception, 
      no data is saved back to the associated file. Otherwise, if it
      invokes <cim><front>PStore</front><back>commit</back></cim>, or if it terminates normally, the
      object hierarchies are written back to the file. The value
      returned is the value returned by the block.
<p/>
      </desc>
    </method>
<p/>
  </methods>
<p/>
</class>
<p/>
<class name="Tempfile" super="[IO]" type="class" ref="xref-000009">  
<p/>
<codefragment>
<fullcode><![CDATA[      require "tempfile"
      
      tf = Tempfile.new("afile")
      tf.path
      tf.puts("Cosi Fan Tutte")
      tf.close
      tf.open
      tf.gets
      tf.close(true)
]]></fullcode><rubycode>
<tr>
<td colspan="3"><tt>require<nbsp/>"tempfile"</tt></td>
</tr>
<tr>
<td colspan="3"><tt></tt></td>
</tr>
<tr>
<td colspan="3"><tt>tf<nbsp/>=<nbsp/>Tempfile.new("afile")</tt></td>
</tr>
<tr>
  <td><tt>tf.path</tt></td>
  <td>&#187;</td>
  <td><tt>"/tmp/afile19701.0"</tt></td>
</tr>
<tr>
  <td><tt>tf.puts("Cosi<nbsp/>Fan<nbsp/>Tutte")</tt></td>
  <td>&#187;</td>
  <td><tt>nil</tt></td>
</tr>
<tr>
  <td><tt>tf.close</tt></td>
  <td>&#187;</td>
  <td><tt>nil</tt></td>
</tr>
<tr>
  <td><tt>tf.open</tt></td>
  <td>&#187;</td>
  <td><tt>#&lt;File:0x40195040&gt;</tt></td>
</tr>
<tr>
  <td><tt>tf.gets</tt></td>
  <td>&#187;</td>
  <td><tt>"Cosi<nbsp/>Fan<nbsp/>Tutte\n"</tt></td>
</tr>
<tr>
  <td><tt>tf.close(true)</tt></td>
  <td>&#187;</td>
  <td><tt>#&lt;File:0x40195040&gt;</tt></td>
</tr>
</rubycode>
<p/>
</codefragment>
<p/>
  Class <classname>Tempfile</classname> creates managed temporary files. Although they
  behave the same as any other <classname>IO</classname> objects, temporary files are
  automatically deleted when the Ruby program terminates. Once a
  <classname>Tempfile</classname> object has been created, the underlying file may be
  opened and closed a number of times in succession.
<p/>
  <classname>Tempfile</classname> does not directly inherit from <classname>IO</classname>. Instead, it
  delegates calls to a <classname>File</classname> object. From the programmer's
  perspective, apart from the unusual <meth>new</meth>, <meth>open,</meth> and
  <meth>close</meth> semantics, a <classname>Tempfile</classname> object behaves as if it
  were an <classname>IO</classname> object.
<p/>
  <methods type="class">
        <method name="new" ref="new">
      <callseq>
        Tempfile.new( <obj>basename</obj>,
        <obj>tmpdir</obj>=&lt;see below&gt; )
        <returns><obj>ref</obj></returns>
      </callseq>
      <desc>
<p/>
      Constructs a temporary file in the given directory. The file
      name is built by concatenating <obj>basename</obj>, the current
      process id and (as an extension) a unique sequence number. If
      the <obj>tmpdir</obj> parameter is not supplied, it defaults to the
      value of one of the environment variables <tt>TMPDIR</tt>, <tt>TMP</tt>, 
      or <tt>TEMP</tt>, or to the directory <tt>/tmp</tt>.      
<p/>
      The file is then opened using mode ``w+'', which allows reading
      and writing and deletes any existing content (see Table
      22.5 on page 326).
<p/>
      </desc>
    </method>
<p/>
  </methods>
<p/>
      <method name="open" ref="open">
      <callseq>
        Tempfile.open( <obj>basename</obj>,
      <obj>tmpdir</obj> )
      <returns><obj>ref</obj></returns>
      </callseq>
      <desc>
<p/>
    Synonym for <ccm><front>Tempfile</front><back>new</back></ccm>.
<p/>
      </desc>
    </method>
<p/>
  <methods type="instance">
        <method name="close" ref="close">
      <callseq>
        <obj>ref</obj>.close( <obj>final</obj>=<const>false</const> )
      </callseq>
      <desc>
<p/>
      Closes <obj>ref</obj>. If <obj>final</obj> is <const>true</const>, deletes the underlying
      real file. If <obj>final</obj> is <const>false</const>, <obj>ref</obj> may be
      subsequently reopened. In all cases, the underlying file is
      deleted when the program terminates.
<p/>
      </desc>
    </method>
<p/>
        <method name="open" ref="open">
      <callseq>
        <obj>ref</obj>.open
      </callseq>
      <desc>
<p/>
      Reopens <obj>ref</obj> using mode ``r+'', which allows reading and
      writing but does not delete existing content.
<p/>
      </desc>
    </method>
<p/>
        <method name="path" ref="path">
      <callseq>
        <obj>ref</obj>.path <returns><obj>aString</obj></returns>
      </callseq>
      <desc>
<p/>
      Returns the full path of the underlying file.
<p/>
      </desc>
    </method>
<p/>
  </methods>
<p/>
</class>
<p/>
<class name="Mutex" super="Object" type="class" ref="xref-000010">  
<p/>
<codefragment>
<alltt><fullcode><![CDATA[      require 'thread'
      sema4 = Mutex.new
      
      a = Thread.new {
        sema4.synchronize {
          # access shared resource
        }
      }

      b = Thread.new {
        sema4.synchronize {
          # access shared resource
        }
      }
]]></fullcode>
require<nbsp/>'thread'
sema4<nbsp/>=<nbsp/>Mutex.new
<p/>
a<nbsp/>=<nbsp/>Thread.new<nbsp/>{
<nbsp/><nbsp/>sema4.synchronize<nbsp/>{
<nbsp/><nbsp/><nbsp/><nbsp/>#<nbsp/>access<nbsp/>shared<nbsp/>resource
<nbsp/><nbsp/>}
}
<p/>
b<nbsp/>=<nbsp/>Thread.new<nbsp/>{
<nbsp/><nbsp/>sema4.synchronize<nbsp/>{
<nbsp/><nbsp/><nbsp/><nbsp/>#<nbsp/>access<nbsp/>shared<nbsp/>resource
<nbsp/><nbsp/>}
}
</alltt>
</codefragment>
<p/>
  <classname>Mutex</classname> implements a simple semaphore that can be used to
  coordinate access to shared data from multiple concurrent threads.
<p/>
  <methods type="instance">
<p/>
          <method name="lock" ref="lock">
      <callseq>
        <obj>ref</obj>.lock
            <returns><obj>ref</obj></returns>
      </callseq>
      <desc>
<p/>
        Attempts to grab the lock and waits if it isn't available.
<p/>
      </desc>
    </method>
<p/>
          <method name="locked?" ref="locked_qm">
      <callseq>
        <obj>ref</obj>.locked?
            <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
          Returns <const>true</const> if this lock is currently held by some
          thread.
<p/>
      </desc>
    </method>
<p/>
          <method name="synchronize" ref="synchronize">
      <callseq>
        <obj>ref</obj>.synchronize <block>{ <blockbody>block</blockbody> }</block>
<returns><obj>ref</obj></returns>
      </callseq>
      <desc>
<p/>
          Obtains a lock (using <cim><front>Mutex</front><back>lock</back></cim>), runs the block, 
          and releases the lock when the block completes.
<p/>
      </desc>
    </method>
<p/>
          <method name="try_lock" ref="try_lock">
      <callseq>
        <obj>ref</obj>.try_lock <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
        Attempts to obtain the lock and returns
        immediately. Returns <const>true</const> if the lock was granted.
<p/>
      </desc>
    </method>
<p/>
          <method name="unlock" ref="unlock">
      <callseq>
        <obj>ref</obj>.unlock
            <returns><obj>ref</obj> or <tt>nil</tt></returns>
      </callseq>
      <desc>
<p/>
          Releases the lock. Returns <tt>nil</tt> if <obj>ref</obj> wasn't locked.
<p/>
      </desc>
    </method>
<p/>
    </methods>
<p/>
</class>
<p/>
<class name="ConditionVariable" super="Object" type="class" ref="xref-000011">
<p/>
<codefragment>
<alltt><fullcode><![CDATA[      require 'thread'
      mutex = Mutex.new
      resource = ConditionVariable.new

      a = Thread.new {
        mutex.synchronize {
          # Thread 'a' now needs the resource
          resource.wait(mutex)
          # 'a' can now have the resource
        }
      }

      b = Thread.new {
        mutex.synchronize {
          # Thread 'b' has finished using the resource
          resource.signal
        }
      }
]]></fullcode>
require<nbsp/>'thread'
mutex<nbsp/>=<nbsp/>Mutex.new
resource<nbsp/>=<nbsp/>ConditionVariable.new
<p/>
a<nbsp/>=<nbsp/>Thread.new<nbsp/>{
<nbsp/><nbsp/>mutex.synchronize<nbsp/>{
<nbsp/><nbsp/><nbsp/><nbsp/>#<nbsp/>Thread<nbsp/>'a'<nbsp/>now<nbsp/>needs<nbsp/>the<nbsp/>resource
<nbsp/><nbsp/><nbsp/><nbsp/>resource.wait(mutex)
<nbsp/><nbsp/><nbsp/><nbsp/>#<nbsp/>'a'<nbsp/>can<nbsp/>now<nbsp/>have<nbsp/>the<nbsp/>resource
<nbsp/><nbsp/>}
}
<p/>
b<nbsp/>=<nbsp/>Thread.new<nbsp/>{
<nbsp/><nbsp/>mutex.synchronize<nbsp/>{
<nbsp/><nbsp/><nbsp/><nbsp/>#<nbsp/>Thread<nbsp/>'b'<nbsp/>has<nbsp/>finished<nbsp/>using<nbsp/>the<nbsp/>resource
<nbsp/><nbsp/><nbsp/><nbsp/>resource.signal
<nbsp/><nbsp/>}
}
</alltt>
</codefragment>
<p/>
  <classname>ConditionVariable</classname> objects augment class <classname>Mutex</classname>. Using
  condition variables, it is possible to suspend while in the middle
  of a critical section until a resource becomes available (see the discussion
  on page 117).
<p/>
    <methods type="instance">
<p/>
          <method name="broadcast" ref="broadcast">
      <callseq>
        <obj>ref</obj>.broadcast
      </callseq>
      <desc>
<p/>
          Wakes up all threads waiting for this lock.
<p/>
      </desc>
    </method>
<p/>
          <method name="signal" ref="signal">
      <callseq>
        <obj>ref</obj>.signal
      </callseq>
      <desc>
<p/>
          Wakes up the first thread in line waiting for this lock.
<p/>
      </desc>
    </method>
<p/>
          <method name="wait" ref="wait">
      <callseq>
        <obj>ref</obj>.wait( <obj>aMutex</obj> )
            <returns><obj>aMutex</obj></returns>
      </callseq>
      <desc>
<p/>
          Releases the lock held in <obj>aMutex</obj> and waits; reacquires
          the lock on wakeup.
<p/>
      </desc>
    </method>
<p/>
    </methods>
<p/>
</class>
<p/>
<library name="timeout">
<p/>
<codefragment>
<alltt><fullcode><![CDATA[      require "timeout"

      for snooze in 1..2
        puts "About to sleep for #{snooze}"
        timeout(1.5) do 
          sleep(snooze)
        end
        puts "That was refreshing"
      end
]]></fullcode>
require<nbsp/>"timeout"
<p/>
for<nbsp/>snooze<nbsp/>in<nbsp/>1..2
<nbsp/><nbsp/>puts<nbsp/>"About<nbsp/>to<nbsp/>sleep<nbsp/>for<nbsp/>#{snooze}"
<nbsp/><nbsp/>timeout(1.5)<nbsp/>do
<nbsp/><nbsp/><nbsp/><nbsp/>sleep(snooze)
<nbsp/><nbsp/>end
<nbsp/><nbsp/>puts<nbsp/>"That<nbsp/>was<nbsp/>refreshing"
end
</alltt>
</codefragment>
<em>produces:</em>
<codefragment><alltt>
About<nbsp/>to<nbsp/>sleep<nbsp/>for<nbsp/>1
That<nbsp/>was<nbsp/>refreshing
About<nbsp/>to<nbsp/>sleep<nbsp/>for<nbsp/>2
/tc/usr/lib/ruby/1.6/timeout.rb:37:<nbsp/>execution<nbsp/>expired<nbsp/>(TimeoutError)
	from<nbsp/>prog.rb:5:in<nbsp/>`timeout'
	from<nbsp/>prog.rb:5
	from<nbsp/>prog.rb:3:in<nbsp/>`each'
	from<nbsp/>prog.rb:3
</alltt>
</codefragment>
<p/>
  The <meth>timeout</meth> method takes a single parameter, representing
  a timeout period in seconds, and a block. The block is executed, and
  a timer is run concurrently. If the block terminates before the
  timeout, <meth>timeout</meth> returns <const>true</const>. Otherwise, a
  <exception>TimeoutError</exception> exception is raised.
<p/>
</library>
<p/>
<class name="WeakRef" super="Delegator" type="class" ref="xref-000012">    
<p/>
<codefragment>
<alltt><fullcode><![CDATA[      require "weakref"
      
      ref = "fol de rol"
      puts "Initial object is #{ref}"
      ref = WeakRef.new(ref)
      puts "Weak reference is #{ref}"
      ObjectSpace.garbage_collect
      puts "But then it is #{ref}"
]]></fullcode>
require<nbsp/>"weakref"
<p/>
ref<nbsp/>=<nbsp/>"fol<nbsp/>de<nbsp/>rol"
puts<nbsp/>"Initial<nbsp/>object<nbsp/>is<nbsp/>#{ref}"
ref<nbsp/>=<nbsp/>WeakRef.new(ref)
puts<nbsp/>"Weak<nbsp/>reference<nbsp/>is<nbsp/>#{ref}"
ObjectSpace.garbage_collect
puts<nbsp/>"But<nbsp/>then<nbsp/>it<nbsp/>is<nbsp/>#{ref}"
</alltt>
</codefragment>
<em>produces:</em>
<codefragment><alltt>
Initial<nbsp/>object<nbsp/>is<nbsp/>fol<nbsp/>de<nbsp/>rol
Weak<nbsp/>reference<nbsp/>is<nbsp/>fol<nbsp/>de<nbsp/>rol
prog.rb:8:<nbsp/>Illegal<nbsp/>Reference<nbsp/>-<nbsp/>probably<nbsp/>recycled<nbsp/>(WeakRef::RefError)
</alltt>
</codefragment>
<p/>
  In Ruby, objects are not eligible for garbage collection if there
  are still references to them. Normally, this is a Good Thing---it
  would be disconcerting to have an object simply evaporate while you
  were using it. However, sometimes you may need more flexibility. For
  example, you might want to implement an in-memory cache of commonly
  used file contents. As you read more files, the cache grows. At some
  point, you may run low on memory. The garbage collector will be
  invoked, but the objects in the cache are all referenced by the
  cache data structures, and so will not be deleted.
<p/>
  A weak reference behaves
  exactly as any normal object reference with one important
  exception---the referenced object may be garbage collected, even
  while references to it exist. In the cache example, if the cached
  files were accessed using weak references, once memory runs low they
  will be garbage collected, freeing memory for the rest of the
  application.
<p/>
  Weak references introduce a slight complexity. As the object
  referenced can be deleted by garbage collection at any time, code
  that accesses these objects must take care to ensure that the
  references are valid. Two techniques can be used. First, the code
  can reference the objects normally. Any attempt to reference an
  object that has been garbage collected will raise a
  <exception>WeakRef::RefError</exception> exception.
<p/>
  An alternative approach is to use the <cim><front>WeakRef</front><back>weakref_alive?</back></cim>
  method to check that a reference is valid before using it. Garbage
  collection must be disabled during the test and subsequent reference
  to the object. In a single-threaded program, you could use something
  like:
<p/>
<codefragment>
<alltt><fullcode><![CDATA[    ref = WeakRef.new(someObject)
    #
    # .. some time later
    #

    gcWasDisabled = GC.disable
    if ref.weakref_alive?
      # do stuff with 'ref'
    end
    GC.enable unless gcWasDisabled
]]></fullcode>
ref<nbsp/>=<nbsp/>WeakRef.new(someObject)
#
#<nbsp/>..<nbsp/>some<nbsp/>time<nbsp/>later
#
<p/>
gcWasDisabled<nbsp/>=<nbsp/>GC.disable
if<nbsp/>ref.weakref_alive?
<nbsp/><nbsp/>#<nbsp/>do<nbsp/>stuff<nbsp/>with<nbsp/>'ref'
end
GC.enable<nbsp/>unless<nbsp/>gcWasDisabled
</alltt>
</codefragment>
<p/>
  <methods type="class">
        <method name="new" ref="new">
      <callseq>
        WeakRef.new( <obj>anObject</obj> )
        <returns><obj>ref</obj></returns>
      </callseq>
      <desc>
<p/>
      Creates and returns a weak reference to <obj>anObject</obj>. All
      future references to <obj>anObject</obj> should be made using <obj>ref</obj>.
<p/>
      </desc>
    </method>
<p/>
  </methods>
<p/>
  <methods type="instance">
<p/>
        <method name="weakref_alive?" ref="weakref_alive_qm">
      <callseq>
        <obj>ref</obj>.weakref_alive?
        <returns><const>true</const> or <const>false</const></returns>
      </callseq>
      <desc>
<p/>
      Returns <const>false</const> if the object referenced by <obj>ref</obj> has
      been garbage collected.
<p/>
      </desc>
    </method>
<p/>
  </methods>
<p/>
</class>
<p/>
</chapter>
</ppdoc>
