ruby.xml #1

  • //
  • guest/
  • perforce_software/
  • p4ruby/
  • main/
  • docbook/
  • xml/
  • ruby.xml
  • View
  • Commits
  • Open Download .zip Download (147 KB)
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="http://www.oasis-open.org/docbook/xml/5.0/rng/docbookxi.rng" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="http://www.oasis-open.org/docbook/xml/5.0/rng/docbook.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<!-- vim: set ts=2 sw=2 tw=80 ai si: -->
<book
        xmlns="http://docbook.org/ns/docbook"
        xmlns:xi="http://www.w3.org/2001/XInclude"
        xmlns:xlink="http://www.w3.org/1999/xlink"
        version="5.0"
        ><?dbhtml filename="copyright.html"?>

  <title>P4Ruby 3000.0.0</title>
  <subtitle>October 2014</subtitle>

  <info>
    <publishername>Perforce</publishername>
    <xi:include href="@common-xml@/legalnotice.xml"/>
    <copyright>
      <year>2014</year>
      <holder>Perforce Software.</holder>
    </copyright>
  </info>

  <chapter xml:id="ruby.intro">
    <title>Introduction</title>

    <para>
      P4Ruby is an extension to the Ruby programming language that allows you to
      run Perforce commands from within Ruby scripts, and get the results in a
      Ruby-friendly format.
    </para>

    <para>
      The main features are:
    </para>

    <itemizedlist>
      <listitem>
        <para>
          Get Perforce data and forms in hashes and arrays.
        </para>
      </listitem>

      <listitem>
        <para>
          Edit Perforce forms by modifying hashes.
        </para>
      </listitem>

      <listitem>
        <para>
          Exception based error handling.
        </para>
      </listitem>

      <listitem>
        <para>
          Controllable handling of warnings such as "File(s) up-to-date." on a
          sync.
        </para>
      </listitem>

      <listitem>
        <para>
          Run as many commands on a connection as required.
        </para>
      </listitem>

      <listitem>
        <para>
          The output of a command is returned as a Ruby array. For non-tagged
          output, the elements of the array are strings. For tagged output, the
          elements of the array are Ruby hashes. For forms, the output is an
          array of <literal>P4::Spec</literal> objects.
        </para>
      </listitem>

      <listitem>
        <para>
          Thread-safe and thread-friendly; you can have multiple instances of
          the <literal>P4</literal> class running in different threads.
        </para>
      </listitem>

      <listitem>
        <para>
          Exception-based error handling. Trap
          <exceptionname>P4Exception</exceptionname>s for complete, high-level
          error handling.
        </para>
      </listitem>
    </itemizedlist>

    <para>
      The most recent release of P4Ruby is 2014.1.
    </para>
  </chapter>

  <chapter xml:id="ruby.requirements">
    <title>System Requirements</title>

    <para>
      P4Ruby is supported on Windows, Linux, Solaris, OS X, and FreeBSD.
    </para>

    <para>
      To build P4Ruby, your development machine must also have:
    </para>

    <itemizedlist>
      <listitem>
        <para>
          Ruby 1.8 or 1.9 development files.
        </para>
      </listitem>

      <listitem>
        <para>
          <command>make</command> (or <command>nmake</command> on Windows).
        </para>
      </listitem>

      <listitem>
        <para>
          The 2014.1 Perforce C/C++ API for your target platform. Older releases
          might work, but are not supported.
        </para>
      </listitem>

      <listitem>
        <para>
          The same C++ compiler used to build the Perforce C++ API on your
          target platform.
        </para>

        <para>
          (If you get "unresolved symbol" errors when building or running
          P4Ruby, you probably used the wrong compiler or the wrong Perforce API
          build.)
        </para>
      </listitem>
    </itemizedlist>
  </chapter>

  <chapter xml:id="ruby.installation">
    <title>Installing P4Ruby</title>

    <para>
      You can download P4Ruby from the Perforce web site:
    </para>

    <para>
      <link xlink:href="http://www.perforce.com/product/components/apis">http://www.perforce.com/product/components/apis</link>
    </para>

    <para>
      After downloading, you can either run the installer or build the interface
      from source, as described in the release notes.
    </para>
  </chapter>

  <chapter xml:id="ruby.programming">
    <title>Programming with P4Ruby</title>

    <para>
      The following example shows how to create a new client workspace based on
      an existing template:
    </para>

<programlisting language="ruby">
require "P4"
template = "my-client-template"
client_root = 'c:\p4-work'
p4 = P4.new
p4.connect

begin

    # Run a "p4 client -t template -o" and convert it into a Ruby hash
    spec = p4.fetch_client( "-t", template, "my-new-client")

    # Now edit the fields in the form
    spec[ "Root" ]  = client_root
    spec[ "Options" ] = spec[ "Options" ].sub( "normdir", "rmdir" )

    # Now save the updated spec
    p4.save_client( spec )

    # Point to the newly-created client
    p4.client="my-new-client"

    # And sync it.
    p4.run_sync

rescue P4Exception
    # If any errors occur, we'll jump in here. Just log them
    # and raise the exception up to the higher level

    p4.errors.each { |e| $stderr.puts( e ) }
    raise

end
</programlisting>

    <section xml:id="ruby.programming.ssl">
      <title>Connecting to SSL-enabled servers</title>

      <para>
        Scripts written with P4Ruby use any existing <envar>P4TRUST</envar> file
        present in their operating environment (by default,
        <filename>.p4trust</filename> in the home directory of the user that
        runs the script).
      </para>

      <para>
        If the fingerprint returned by the server fails to match the one
        installed in the <envar>P4TRUST</envar> file associated with the
        script's run-time environment, your script will (and should!) fail to
        connect to the server.
      </para>
    </section>
  </chapter>

  <chapter xml:id="ruby.classes">
    <title>P4Ruby classes</title>

    <para>
      The P4 module consists of several public classes:
    </para>

    <itemizedlist>
      <listitem><para><xref linkend="ruby.classes.p4"/></para></listitem>
      <listitem><para><xref linkend="ruby.classes.p4exception"/></para></listitem>
      <listitem><para><xref linkend="ruby.classes.p4_depotfile"/></para></listitem>
      <listitem><para><xref linkend="ruby.classes.p4_revision"/></para></listitem>
      <listitem><para><xref linkend="ruby.classes.p4_integration"/></para></listitem>
      <listitem><para><xref linkend="ruby.classes.p4_map"/></para></listitem>
      <listitem><para><xref linkend="ruby.classes.p4_mergedata"/></para></listitem>
      <listitem><para><xref linkend="ruby.classes.p4_message"/></para></listitem>
      <listitem><para><xref linkend="ruby.classes.p4_outputhandler"/></para></listitem>
      <listitem><para><xref linkend="ruby.classes.p4_progress"/></para></listitem>
      <listitem><para><xref linkend="ruby.classes.p4_spec"/></para></listitem>
    </itemizedlist>

    <para>
      The following tables provide brief details about each public class.
    </para>

    <section xml:id="ruby.classes.p4">
      <title>P4</title>

      <para>
        The main class used for executing Perforce commands. Almost everything
        you do with P4Ruby will involve this class.
      </para>

      <informaltable>
        <tgroup cols="2">
          <colspec colname="method" colwidth="*"/>
          <colspec colname="description" colwidth="3*"/>
          <thead>
            <row>
              <entry>
                <para>
                  Method
                </para>
              </entry>

              <entry>
                <para>
                  Description
                </para>
              </entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.identify"><methodname>identify</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Return the version of P4Ruby in use (class method).
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.new"><methodname>new</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Construct a new <classname>P4</classname> object (class method).
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.api_level.eq"><methodname>api_level=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set desired API compatibility level.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.api_level"><methodname>api_level</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Return current API compatibility level.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.at_exception_level"><methodname>at_exception_level</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Execute the associated block under a specific exception level,
                  returning to previous exception level when block returns.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.charset.eq"><methodname>charset=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set character set when connecting to Unicode servers.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.charset"><methodname>charset</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get character set when connecting to Unicode servers.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.client.eq"><methodname>client=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set client workspace (<envar>P4CLIENT</envar>).
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.client"><methodname>client</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get current client workspace (<envar>P4CLIENT</envar>).
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.connect"><methodname>connect</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Connect to the Perforce Server, raise
                  <exceptionname>P4Exception</exceptionname> on failure.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.connected"><methodname>connected?</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Test whether or not session has been connected and/or has been
                  dropped.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.cwd.eq"><methodname>cwd=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set current working directory.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.cwd"><methodname>cwd</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get current working directory.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.delete_spectype"><methodname>delete_<replaceable>&lt;spectype&gt;</replaceable></methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Shortcut methods for deleting clients, labels, etc.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.disconnect"><methodname>disconnect</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Disconnect from the Perforce Server.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.each_spectype"><methodname>each_<replaceable>&lt;spectype&gt;</replaceable></methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Shortcut methods for iterating through clients, labels, etc.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.env"><methodname>env</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get the value of a Perforce environment variable, taking into
                  account <envar>P4CONFIG</envar> files and (on Windows or OS X)
                  the registry or user preferences.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.errors"><methodname>errors</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Return the array of errors that occurred during execution of
                  previous command.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <methodname>
                    <link linkend="ruby.p4.exception_level.eq">exception_level=</link>
                  </methodname>
                </para>
              </entry>

              <entry>
                <para>
                  Control which types of events give rise to exceptions
                  (<exceptionname>P4::RAISE_NONE</exceptionname>,
                  <exceptionname>RAISE_ERRORS</exceptionname>, or
                  <exceptionname>RAISE_ALL</exceptionname>).
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.exception_level"><methodname>exception_level</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Return the current exception level.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                <link linkend="ruby.p4.fetch_spectype"><methodname>fetch_<replaceable>&lt;spectype&gt;</replaceable></methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Shortcut methods for retrieving the definitions of clients, labels, etc.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.format_spec"><methodname>format_spec</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Convert fields in a hash containing the elements of a Perforce
                  form (spec) into the string representation familiar to users.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.format_spectype"><methodname>format_<replaceable>&lt;spectype&gt;</replaceable></methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Shortcut method; equivalent to:
                </para>

<programlisting>
p4.format_spec( "<replaceable>&lt;spectype&gt;</replaceable>", aHash )
</programlisting>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.handler.eq"><methodname>handler=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set output handler.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.handler"><methodname>handler</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get output handler.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.host.eq"><methodname>host=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set the name of the current host (<envar>P4HOST</envar>).
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.host"><methodname>host</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get the current hostname.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.input.eq"><methodname>input=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Store input for next command.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.maxlocktime.eq"><methodname>maxlocktime=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set MaxLockTime used for all following commands.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.maxlocktime"><methodname>maxlocktime</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get MaxLockTime used for all following commands.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.maxresults.eq"><methodname>maxresults=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set MaxResults used for all following commands.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.maxresults"><methodname>maxresults</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get MaxResults used for all following commands.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.maxscanrows.eq"><methodname>maxscanrows=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set MaxScanRows used for all following commands.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.maxscanrows"><methodname>maxscanrows</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get MaxScanRows used for all following commands.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.messages"><methodname>messages</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns all messages from the server as
                  <classname>P4::Message</classname> objects.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.p4config_file"><methodname>p4config_file</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get the location of the configuration file used
                  (<envar>P4CONFIG</envar>).
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.parse_spectype"><methodname>parse_<replaceable>&lt;spectype&gt;</replaceable></methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Shortcut method; equivalent to:
                </para>

<programlisting language="ruby">
p4.parse_spec( "<replaceable>&lt;spectype&gt;</replaceable>", aString )
</programlisting>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.parse_spec"><methodname>parse_spec</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Parses a Perforce form (spec) in text form into a Ruby hash
                  using the spec definition obtained from the server.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.password.eq"><methodname>password=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set Perforce password (<envar>P4PASSWD</envar>).
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.password"><methodname>password</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get the current password or ticket.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.port.eq"><methodname>port=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set host and port (<envar>P4PORT</envar>).
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.port"><methodname>port</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get host and port (<envar>P4PORT</envar>) of the current
                  Perforce server.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.prog.eq"><methodname>prog=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set program name as shown by <command>p4 monitor show
                  -e</command>.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.prog"><methodname>prog</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get program name as shown by <command>p4 monitor show
                  -e</command>.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.progress.eq"><methodname>progress=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set progress indicator.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.progress"><methodname>progress</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get progress indicator.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.run_cmd"><methodname>run_<replaceable>cmd</replaceable></methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Shortcut method; equivalent to:
                </para>

<programlisting language="ruby">
p4.run( "<replaceable>cmd</replaceable>", <replaceable>arguments</replaceable>... )
</programlisting>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.run"><methodname>run</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Runs the specified Perforce command with the arguments
                  supplied.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.run_filelog"><methodname>run_filelog</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Runs a <command>p4 filelog</command> on the fileSpec provided,
                  returns an array of <classname>P4::DepotFile</classname>
                  objects.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.run_login"><methodname>run_login</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Runs <command>p4 login</command> using a password or ticket
                  set by the user.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.run_password"><methodname>run_password</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  A thin wrapper to make it easy to change your password.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.run_resolve"><methodname>run_resolve</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Interface to <command>p4 resolve</command>.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.run_submit"><methodname>run_submit</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Submit a changelist to the server.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.run_tickets"><methodname>run_tickets</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get a list of tickets from the local tickets file.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.save_spectype"><methodname>save_<replaceable>&lt;spectype&gt;</replaceable></methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Shortcut method; equivalent to:
                </para>

<programlisting language="ruby">
p4.input = hashOrString
p4.run( "<replaceable>&lt;spectype&gt;</replaceable>", "-i" )
</programlisting>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.server_case_sensitive"><methodname>server_case_sensitive?</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Detects whether or not the server is case sensitive.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.server_level"><methodname>server_level</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the current Perforce server level.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.server_unicode"><methodname>server_unicode?</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Detects whether or not the server is in unicode mode.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.set_env"><methodname>set_env</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  On Windows or OS X, set a variable in the registry or user preferences.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.streams.eq"><methodname>streams=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Enable or disable support for streams.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.streams"><methodname>streams?</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Test whether or not the server supports streams
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.tagged"><methodname>tagged</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Toggles tagged output (true or false). By default, tagged output is on.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.tagged.eq"><methodname>tagged=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Sets tagged output. By default, tagged output is on.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.tagged.q"><methodname>tagged?</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Detects whether or not tagged output is enabled.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.ticketfile.eq"><methodname>ticketfile=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set the location of the <envar>P4TICKETS</envar> file.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.ticketfile"><methodname>ticketfile</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get the location of the <envar>P4TICKETS</envar> file.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.track.eq"><methodname>track=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Activate or disable server performance tracking.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.track"><methodname>track?</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Detect whether server performance tracking is active.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.track_output"><methodname>track_output</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns server tracking output.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.user.eq"><methodname>user=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set the Perforce username (<envar>P4USER</envar>).
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.user"><methodname>user</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get the Perforce username (<envar>P4USER</envar>).
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.version.eq"><methodname>version=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set your script's version as reported to the server.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.version"><methodname>version</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Get your script's version as reported by the server.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4.warnings"><methodname>warnings</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the array of warnings that arose during execution of
                  the last command.
                </para>
              </entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
    </section>

    <section xml:id="ruby.classes.p4exception">
      <title>P4Exception</title>

      <para>
        Used as part of error reporting and is derived from the Ruby
        <classname>RuntimeError</classname> class.
      </para>
    </section>

    <section xml:id="ruby.classes.p4_depotfile">
      <title>P4::DepotFile</title>

      <para>
        Utility class allowing access to the attributes of a file in the depot.
        Returned by <methodname>P4#run_filelog()</methodname>.
      </para>

      <informaltable>
        <tgroup cols="2">
          <colspec colname="method" colwidth="*"/>
          <colspec colname="description" colwidth="3*"/>
          <thead>
            <row>
              <entry>
                <para>
                  Method
                </para>
              </entry>

              <entry>
                <para>
                  Description
                </para>
              </entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_depotfile.depot_file"><methodname>depot_file</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Name of the depot file to which this object refers.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_depotfile.each_revision"><methodname>each_revision</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Iterates over each revision of the depot file.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_depotfile.revisions"><methodname>revisions</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns an array of revision objects for the depot file.
                </para>
              </entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
    </section>

    <section xml:id="ruby.classes.p4_revision">
      <title>P4::Revision</title>

      <para>
        Utility class allowing access to the attributes of a revision
        <classname>P4::DepotFile</classname> object. Returned by
        <methodname>P4#run_filelog()</methodname>.
      </para>

      <informaltable>
        <tgroup cols="2">
          <colspec colname="method" colwidth="*"/>
          <colspec colname="description" colwidth="3*"/>
          <thead>
            <row>
              <entry>
                <para>
                  Method
                </para>
              </entry>

              <entry>
                <para>
                  Description
                </para>
              </entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_revision.action"><methodname>action</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Action that created the revision.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_revision.change"><methodname>change</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Changelist number.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_revision.client"><methodname>client</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Client workspace used to create this revision.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_revision.depot_file"><methodname>depot_file</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Name of the file in the depot.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_revision.desc"><methodname>desc</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Short changelist description.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_revision.digest"><methodname>digest</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  MD5 digest of this revision.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_revision.filesize"><methodname>filesize</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the size of this revision.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_revision.integrations"><methodname>integrations</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Array of <classname>P4::Integration</classname> objects.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_revision.rev"><methodname>rev</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Revision number.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_revision.time"><methodname>time</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Timestamp.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_revision.type"><methodname>type</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Perforce file type.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_revision.user"><methodname>user</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  User that created this revision.
                </para>
              </entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
    </section>

    <section xml:id="ruby.classes.p4_integration">
      <title>P4::Integration</title>

      <para>
        Utility class allowing access to the attributes of an integration record
        for a <classname>P4::Revision</classname> object. Returned by
        <methodname>P4#run_filelog()</methodname>.
      </para>

      <informaltable>
        <tgroup cols="2">
          <colspec colname="method" colwidth="*"/>
          <colspec colname="description" colwidth="3*"/>
          <thead>
            <row>
              <entry>
                <para>
                  Method
                </para>
              </entry>

              <entry>
                <para>
                  Description
                </para>
              </entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_integration.how"><methodname>how</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Integration method (merge/branch/copy/ignored).
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_integration.file"><methodname>file</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Integrated file.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_integration.srev"><methodname>srev</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Start revision.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_integration.erev"><methodname>erev</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  End revision.
                </para>
              </entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
    </section>

    <section xml:id="ruby.classes.p4_map">
      <title>P4::Map</title>

      <para>
        A class that allows users to create and work with Perforce mappings
        without requiring a connection to the Perforce Server.
      </para>

      <informaltable>
        <tgroup cols="2">
          <colspec colname="method" colwidth="*"/>
          <colspec colname="description" colwidth="3*"/>
          <thead>
            <row>
              <entry>
                <para>
                  Method
                </para>
              </entry>

              <entry>
                <para>
                  Description
                </para>
              </entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_map.new"><methodname>new</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Construct a new map object (class method).
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_map.join"><methodname>join</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Joins two maps to create a third (class method).
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_map.clear"><methodname>clear</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Empties a map.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_map.count"><methodname>count</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the number of entries in a map.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_map.empty"><methodname>empty?</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Tests whether or not a map object is empty.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_map.insert"><methodname>insert</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Inserts an entry into the map.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_map.translate"><methodname>translate</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Translate a string through a map.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_map.includes"><methodname>includes?</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Tests whether a path is mapped.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_map.reverse"><methodname>reverse</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns a new mapping with the left and right sides reversed.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_map.lhs"><methodname>lhs</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the left side as an array.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_map.rhs"><methodname>rhs</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the right side as an array.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_map.to_a"><methodname>to_a</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the map as an array.
                </para>
              </entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
    </section>

    <section xml:id="ruby.classes.p4_mergedata">
      <title>P4::MergeData</title>

      <para>
        Class encapsulating the context of an individual merge during execution
        of a <command>p4 resolve</command> command. Passed as a parameter to the
        block passed to <methodname>P4#run_resolve()</methodname>.
      </para>

      <informaltable>
        <tgroup cols="2">
          <colspec colname="method" colwidth="*"/>
          <colspec colname="description" colwidth="3*"/>
          <thead>
            <row>
              <entry>
                <para>
                  Method
                </para>
              </entry>

              <entry>
                <para>
                  Description
                </para>
              </entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_mergedata.your_name"><methodname>your_name</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the name of "your" file in the merge. (file in
                  workspace)
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_mergedata.their_name"><methodname>their_name</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the name of "their" file in the merge. (file in the
                  depot)
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_mergedata.base_name"><methodname>base_name</methodname></link>
                </para>
              </entry>
              <entry>
                <para>
                  Returns the name of "base" file in the merge. (file in the
                  depot)
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_mergedata.your_path"><methodname>your_path</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the path of "your" file in the merge. (file in
                  workspace)
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_mergedata.their_path"><methodname>their_path</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the path of "their" file in the merge. (temporary file
                  on workstation into which <methodname>their_name</methodname>
                  has been loaded)
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_mergedata.base_path"><methodname>base_path</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the path of the base file in the merge. (temporary
                  file on workstation into which
                  <methodname>base_name</methodname> has been loaded)
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_mergedata.result_path"><methodname>result_path</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the path to the merge result. (temporary file on
                  workstation into which the automatic merge performed by the
                  server has been loaded)
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_mergedata.merge_hint"><methodname>merge_hint</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns hint from server as to how user might best resolve
                  merge.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_mergedata.run_merge"><methodname>run_merge</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  If the environment variable <envar>P4MERGE</envar> is defined,
                  run it and return a boolean based on the return value of that
                  program.
                </para>
              </entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
    </section>

    <section xml:id="ruby.classes.p4_message">
      <title>P4::Message</title>

      <para>
        Utility class allowing access to the attributes of a message object
        returned by <methodname>P4#messages()</methodname>.
      </para>

      <informaltable>
        <tgroup cols="2">
          <colspec colname="method" colwidth="*"/>
          <colspec colname="description" colwidth="3*"/>
          <thead>
            <row>
              <entry>
                <para>
                  Method
                </para>
              </entry>

              <entry>
                <para>
                  Description
                </para>
              </entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_message.severity"><methodname>severity</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the severity of the message.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_message.generic"><methodname>generic</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the generic class of the error.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_message.msgid"><methodname>msgid</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the unique ID of the error message.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_message.to_s"><methodname>to_s</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns the error message as a string.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_message.inspect"><methodname>inspect</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Converts the error object into a string for debugging
                  purposes.
                </para>
              </entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
    </section>

    <section xml:id="ruby.classes.p4_outputhandler">
      <title>P4::OutputHandler</title>

      <para>
        Handler class that provides access to streaming output from the server;
        set <methodname>P4#handler()</methodname> to an instance of a subclass of
        <classname>P4::OutputHandler</classname> to enable callbacks:
      </para>

      <informaltable>
        <tgroup cols="2">
          <colspec colname="method" colwidth="*"/>
          <colspec colname="description" colwidth="3*"/>
          <thead>
            <row>
              <entry>
                <para>
                  Method
                </para>
              </entry>
              <entry>
                <para>
                  Description
                </para>
              </entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_outputhandler.outputbinary"><methodname>outputBinary</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Process binary data.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_outputhandler.outputinfo"><methodname>outputInfo</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Process tabular data.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_outputhandler.outputmessage"><methodname>outputMessage</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Process information or errors.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_outputhandler.outputstat"><methodname>outputStat</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Process tagged output.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_outputhandler.outputtext"><methodname>outputText</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Process text data.
                </para>
              </entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
    </section>

    <section xml:id="ruby.classes.p4_progress">
      <title>P4::Progress</title>

      <para>
        Handler class that provides access to progress indicators from the
        server; set <methodname>P4#progress()</methodname> to an instance of a
        subclass of <classname>P4::Progress</classname> with the following
        methods (even if the implementations are empty) to enable callbacks:
      </para>

      <informaltable>
        <tgroup cols="2">
          <colspec colname="method" colwidth="*"/>
          <colspec colname="description" colwidth="3*"/>
          <thead>
            <row>
              <entry>
                <para>
                  Method
                </para>
              </entry>

              <entry>
                <para>
                  Description
                </para>
              </entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_progress.init"><methodname>init</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Initialize progress indicator as designated type.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_progress.total"><methodname>total</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Total number of units (if known).
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_progress.description"><methodname>description</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Description and type of units to be used for progress
                  reporting.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_progress.update"><methodname>update</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  If non-zero, user has requested a cancellation of the
                  operation.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_progress.done"><methodname>done</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  If non-zero, operation has failed.
                </para>
              </entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
    </section>

    <section xml:id="ruby.classes.p4_spec">
      <title>P4::Spec</title>

      <para>
        Subclass of hash allowing access to the fields in a Perforce
        specification form. Also checks that the fields that are set are valid
        fields for the given type of spec. Returned by
        <methodname>P4#fetch_<replaceable>&lt;spectype&gt;</replaceable>()</methodname>.
      </para>

      <informaltable>
        <tgroup cols="2">
          <colspec colname="method" colwidth="*"/>
          <colspec colname="description" colwidth="3*"/>
          <thead>
            <row>
              <entry>
                <para>
                  Method
                </para>
              </entry>

              <entry>
                <para>
                  Description
                </para>
              </entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_spec._fieldname"><methodname>spec.<replaceable>_fieldname</replaceable></methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Return the value associated with the field named
                  <replaceable>fieldname</replaceable>.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_spec._fieldname.eq"><methodname>spec._<replaceable>fieldname</replaceable>=</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Set the value associated with the field named
                  <replaceable>fieldname</replaceable>.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <link linkend="ruby.p4_spec.permitted_fields"><methodname>spec.permitted_fields</methodname></link>
                </para>
              </entry>

              <entry>
                <para>
                  Returns an array containing the names of fields that are valid
                  in this spec object.
                </para>
              </entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
    </section>
  </chapter>

  <chapter xml:id="ruby.p4">
    <title>Class P4</title>

    <section xml:id="ruby.p4-description">
      <title>Description</title>

      <para>
        Main interface to the Perforce client API. Each
        <classname>P4</classname> object provides you with a thread-safe API
        level interface to Perforce. The basic model is to:
      </para>

      <orderedlist>
        <listitem>
          <para>
            Instantiate your <literal>P4</literal> object.
          </para>
        </listitem>

        <listitem>
          <para>
            Specify your Perforce client environment.
          </para>

          <itemizedlist>
            <listitem>
              <para>
                <literal>client</literal>
              </para>
            </listitem>

            <listitem>
              <para>
                <literal>host</literal>
              </para>
            </listitem>

            <listitem>
              <para>
                <literal>password</literal>
              </para>
            </listitem>

            <listitem>
              <para>
                <literal>port</literal>
              </para>
            </listitem>

            <listitem>
              <para>
                <literal>user</literal>
              </para>
            </listitem>
          </itemizedlist>
        </listitem>

        <listitem>
          <para>
            Set any options to control output or error handling:
          </para>

          <itemizedlist>
            <listitem>
              <para>
                <literal>exception_level</literal>
              </para>
            </listitem>
          </itemizedlist>
        </listitem>

        <listitem>
          <para>
            Connect to the Perforce service.
          </para>

          <para>
            The Perforce protocol is not designed to support multiple concurrent
            queries over the same connection. Multithreaded applications that
            use the C++ API or derived APIs (including P4Ruby) should ensure
            that a separate connection is used for each thread, or that only one
            thread may use a shared connection at a time.
          </para>
        </listitem>

        <listitem>
          <para>
            Run your Perforce commands.
          </para>
        </listitem>

        <listitem>
          <para>
            Disconnect from the Perforce service.
          </para>
        </listitem>
      </orderedlist>
    </section>

    <section xml:id="ruby.p4-class_methods">
      <title>Class Methods</title>

      <section xml:id="ruby.p4.identify">
        <title>P4.identify -&gt; aString</title>

        <para>
          Return the version of P4Ruby that you are using. Also reports the
          version of the OpenSSL library used for building the underlying
          Perforce C++ API with which P4Ruby was built.
        </para>

<programlisting language="ruby">
ruby -rP4 -e 'puts( P4.identify )'
</programlisting>

        <para>
          Some of this information is already made available through the
          predefined constants <literal>P4::VERSION</literal>,
          <literal>P4::OS</literal>, and <literal>P4::PATCHLEVEL</literal>.
        </para>
      </section>

      <section xml:id="ruby.p4.new">
        <title>P4.new -&gt; aP4</title>

        <para>
          Constructs a new P4 object.
        </para>

<programlisting language="ruby">
p4 = P4.new()
</programlisting>
      </section>
    </section>

    <section xml:id="ruby.p4-instance_methods">
      <title>Instance Methods</title>

      <section xml:id="ruby.p4.api_level.eq">
        <title>p4.api_level= anInteger -&gt; anInteger</title>

        <para>
          Sets the API compatibility level desired. This is useful when writing
          scripts using Perforce commands that do not yet support tagged output.
          In these cases, upgrading to a later server that supports tagged
          output for the commands in question can break your script. Using this
          method allows you to lock your script to the output format of an older
          Perforce release and facilitate seamless upgrades. This method
          <emphasis>must</emphasis> be called prior to calling
          <methodname>P4#connect()</methodname>.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.api_level = 67 # Lock to 2010.1 format
p4.connect
...
</programlisting>

        <para>
          For the API integer levels that correspond to each Perforce release,
          see:
        </para>

        <para>
          <link xlink:href="http://kb.perforce.com/article/512">http://kb.perforce.com/article/512</link>
        </para>
      </section>

      <section xml:id="ruby.p4.api_level">
        <title>p4.api_level -&gt; anInteger</title>

        <para>
          Returns the current Perforce API compatibility level. Each iteration
          of the Perforce Server is given a level number. As part of the initial
          communication, the client protocol level is passed between client
          application and the Perforce Server. This value, defined in the
          Perforce API, determines the communication protocol level that the
          Perforce client will understand. All subsequent responses from the
          Perforce Server can be tailored to meet the requirements of that
          client protocol level.
        </para>

        <para>
          For more information, see:
        </para>

        <para>
          <link xlink:href="http://kb.perforce.com/article/512">http://kb.perforce.com/article/512</link>
        </para>
      </section>

      <section xml:id="ruby.p4.at_exception_level">
        <title>p4.at_exception_level( lev ) { ... } -&gt; self</title>

        <para>
          Executes the associated block under a specific exception level.
          Returns to the previous exception level when the block returns.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.client = "www"
p4.connect

p4.at_exception_level( P4::RAISE_ERRORS ) do
    p4.run_sync
end

p4.disconnect
</programlisting>
      </section>

      <section xml:id="ruby.p4.charset.eq">
        <title>p4.charset= aString -&gt; aString</title>

        <para>
          Sets the character set to use when connect to a Unicode enabled
          server. Do not use when working with non-Unicode-enabled servers. By
          default, the character set is the value of the
          <envar>P4CHARSET</envar> environment variable. If the character set is
          invalid, this method raises a
          <exceptionname>P4Exception</exceptionname>.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.client = "www"
p4.charset = "iso8859-1"
p4.connect
p4.run_sync
p4.disconnect
</programlisting>
      </section>

      <section xml:id="ruby.p4.charset">
        <title>p4.charset -&gt; aString</title>

        <para>
          Get the name of the character set in use when working with
          Unicode-enabled servers.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.charset = "utf8"
puts( p4.charset )
</programlisting>
      </section>

      <section xml:id="ruby.p4.client.eq">
        <title>p4.client= aString -&gt; aString</title>

        <para>
          Set the name of the client workspace you wish to use. If not called,
          defaults to the value of <envar>P4CLIENT</envar> taken from any
          <envar>P4CONFIG</envar> file present, or from the environment as per
          the usual Perforce convention. Must be called before connecting to the
          Perforce server.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.client = "www"
p4.connect
p4.run_sync
p4.disconnect
</programlisting>
      </section>

      <section xml:id="ruby.p4.client">
        <title>p4.client -&gt; aString</title>

        <para>
          Get the name of the Perforce client currently in use.
        </para>

<programlisting language="ruby">
p4 = P4.new
puts( p4.client )
</programlisting>
      </section>

      <section xml:id="ruby.p4.connect">
        <title>p4.connect -&gt; aBool</title>

        <para>
          Connect to the Perforce Server. You must connect before you can
          execute commands. Raises a <exceptionname>P4Exception</exceptionname>
          if the connection attempt fails.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.connect
</programlisting>
      </section>

      <section xml:id="ruby.p4.connected">
        <title>p4.connected? -&gt; aBool</title>

        <para>
          Test whether or not the session has been connected, and if the
          connection has not been dropped.
        </para>

<programlisting language="ruby">
p4 = P4.newp4.connected?
</programlisting>
      </section>

      <section xml:id="ruby.p4.cwd.eq">
        <title>p4.cwd= aString -&gt; aString</title>

        <para>
          Sets the current working directly. Can be called prior to executing
          any Perforce command. Sometimes necessary if your script executes a
          <function>chdir()</function> as part of its processing.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.cwd = "/home/bruno"
</programlisting>
      </section>

      <section xml:id="ruby.p4.cwd">
        <title>p4.cwd -&gt; aString</title>

        <para>
          Get the current working directory.
        </para>

<programlisting language="ruby">
p4 = P4.new
puts( p4.cwd )
</programlisting>
      </section>

      <section xml:id="ruby.p4.delete_spectype">
        <title>p4.delete_&lt;spectype&gt;( [options], name ) -&gt; anArray</title>

        <para>
          The delete methods are simply shortcut methods that allow you to
          quickly delete the definitions of clients, labels, branches, etc.
          These methods are equivalent to:
        </para>

<programlisting language="ruby">
p4.run( "<replaceable>&lt;spectype&gt;</replaceable>", '-d', [<replaceable>options</replaceable>], "<replaceable>spec name</replaceable>" )
</programlisting>

        <para>
          For example:
        </para>

<programlisting language="ruby">
require "P4"
require "parsedate"
include ParseDate
now = Time.now
p4 = P4.new
begin
  p4.connect
  p4.run_clients.each do
    |client|
    atime = parsedate( client[ "Access" ] )
    if( (atime + 24 * 3600 * 365 ) &lt; now )
      p4.delete_client( '-f', client[ "client" ] )
    end
  end
rescue P4Exception
  p4.errors.each { |e| puts( e ) }
ensure
  p4.disconnect
end
</programlisting>
      </section>

      <section xml:id="ruby.p4.disconnect">
        <title>p4.disconnect -&gt; true</title>

        <para>
          Disconnect from the Perforce Server.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.connect
p4.disconnect
</programlisting>
      </section>

      <section xml:id="ruby.p4.each_spectype">
        <title>p4.each_&lt;spectype&lt;( arguments ) -&gt; anArray</title>

        <para>
          The <methodname>each_<replaceable>&lt;spectype&gt;</replaceable></methodname>
          methods are shortcut methods that allow you to quickly iterate through
          clients, labels, branches, etc. Valid
          <replaceable>&lt;spectype&gt;</replaceable>s are <literal>clients</literal>,
          <literal>labels</literal>, <literal>branches</literal>,
          <literal>changes</literal>, <literal>streams</literal>,
          <literal>jobs</literal>, <literal>users</literal>,
          <literal>groups</literal>, <literal>depots</literal> and
          <literal>servers</literal>. Valid arguments are any arguments that
          would be valid for the corresponding
          <methodname>run_<replaceable>&lt;spectype&gt;</replaceable></methodname>
          command.
        </para>

        <para>
          For example, to iterate through clients:
        </para>

<programlisting language="ruby">
p4.each_clients do
|c|
  # work with the retrieved client spec
end
</programlisting>

        <para>
          is equivalent to:
        </para>

<programlisting language="ruby">
clients = p4.run_clients
clients.each do
|c|
  client = p4.fetch_client( c['client'] )
  # work with the retrieved client spec
end
</programlisting>
      </section>

      <section xml:id="ruby.p4.env">
        <title>p4.env -&gt; string</title>

        <para>
          Get the value of a Perforce environment variable, taking into account
          <envar>P4CONFIG</envar> files and (on Windows and OS X) the registry
          or user preferences.
        </para>

<programlisting language="ruby">
p4 = P4.new
puts p4.env( "P4PORT" )
</programlisting>
      </section>

      <section xml:id="ruby.p4.errors">
        <title>p4.errors -&gt; anArray</title>

        <para>
          Returns the array of errors which occurred during execution of the
          previous command.
        </para>

<programlisting language="ruby">
p4 = P4.new
begin
  p4.connect
  p4.exception_level( P4::RAISE_ERRORS ) # ignore "File(s) up-to-date"
  files = p4.run_sync
rescue P4Exception
  p4.errors.each { |e| puts( e ) }
ensure
  p4.disconnect
end
</programlisting>
      </section>

      <section xml:id="ruby.p4.exception_level.eq">
        <title>p4.exception_level= anInteger -&gt; anInteger</title>

        <para>
          Configures the events which give rise to exceptions. The following
          three levels are supported:
        </para>

        <itemizedlist>
          <listitem>
            <para>
              <literal>P4::RAISE_NONE</literal> disables all exception raising
              and makes the interface completely procedural.
            </para>
          </listitem>

          <listitem>
            <para>
              <literal>P4::RAISE_ERRORS</literal> causes exceptions to be raised
              only when errors are encountered.
            </para>
          </listitem>

          <listitem>
            <para>
              <literal>P4::RAISE_ALL</literal> causes exceptions to be raised
              for both errors and warnings. This is the default.
            </para>

<programlisting language="ruby">
p4 = P4.new
p4.exception_level = P4::RAISE_ERRORS
p4.connect   # P4Exception on failure
p4.run_sync  # File(s) up-to-date is a warning so no exception is raised
p4.disconnect
</programlisting>
          </listitem>
        </itemizedlist>
      </section>

      <section xml:id="ruby.p4.exception_level">
        <title>p4.exception_level -&gt; aNumber</title>

        <para>
          Returns the current exception level.
        </para>
      </section>

      <section xml:id="ruby.p4.fetch_spectype">
        <title>p4.fetch_&lt;spectype&gt;( [name] ) -&gt; aP4::Spec</title>

        <para>
          The <methodname>fetch_<replaceable>&lt;spectype&gt;</replaceable></methodname>
          methods are shortcut methods that allow you to quickly fetch the
          definitions of clients, labels, branches, etc. They're equivalent to:
        </para>

<programlisting language="ruby">
p4.run( "<replaceable>&lt;spectype&gt;</replaceable>", '-o', ... ).shift
</programlisting>

        <para>
          For example:
        </para>

<programlisting language="ruby">
p4 = P4.new
begin
  p4.connect
  client       = p4.fetch_client()
  other_client = p4.fetch_client( "other" )
  label        = p4.fetch_label( "somelabel" )
rescue P4Exception
  p4.errors.each { |e| puts( e ) }
ensure
  p4.disconnect
end
</programlisting>
      </section>

      <section xml:id="ruby.p4.format_spec">
        <title>p4.format_spec( "&lt;spectype&gt;", aHash )-&gt; aString</title>

        <para>
          Converts the fields in a hash containing the elements of a Perforce
          form (spec) into the string representation familiar to users.
        </para>

        <para>
          The first argument is the type of spec to format: for example,
          <literal>client</literal>, <literal>branch</literal>,
          <literal>label</literal>, and so on. The second argument is the hash
          to parse.
        </para>

        <para>
          There are shortcuts available for this method. You can use:
        </para>

<programlisting language="ruby">
p4.format_<replaceable>&lt;spectype&gt;</replaceable>( hash )
</programlisting>

        <para>
          instead of:
        </para>

<programlisting language="ruby">
p4.format_spec( "<replaceable>&lt;spectype&gt;</replaceable>", hash )
</programlisting>

        <para>
          where <replaceable>&lt;spectype&gt;</replaceable> is the name of a Perforce
          spec, such as <literal>client</literal>, <literal>label</literal>,
          etc.
        </para>
      </section>

      <section xml:id="ruby.p4.format_spectype">
        <title>p4.format_&lt;spectype&gt; aHash -&gt; aHash</title>

        <para>
          The
          <methodname>format_<replaceable>&lt;spectype&gt;</replaceable></methodname>
          methods are shortcut methods that allow you to quickly fetch the
          definitions of clients, labels, branches, etc. They're equivalent to:
        </para>

<programlisting language="ruby">
p4.format_spec( "<replaceable>&lt;spectype&gt;</replaceable>", aHash )
</programlisting>
      </section>

      <section xml:id="ruby.p4.handler.eq">
        <title>p4.handler= aHandler -&gt; aHandler</title>

        <para>
          Set the current output handler. This should be a subclass of
          <classname>P4::OutputHandler</classname>.
        </para>
      </section>

      <section xml:id="ruby.p4.handler">
        <title>p4.handler -&gt; aHandler</title>

        <para>
          Get the current output handler.
        </para>
      </section>

      <section xml:id="ruby.p4.host.eq">
        <title>p4.host= aString -&gt; aString</title>

        <para>
          Set the name of the current host. If not called, defaults to the value
          of <envar>P4HOST</envar> taken from any <envar>P4CONFIG</envar> file
          present, or from the environment as per the usual Perforce convention.
          Must be called before connecting to the Perforce server.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.host = "workstation123.perforce.com"
p4.connect
...
p4.disconnect
</programlisting>
      </section>

      <section xml:id="ruby.p4.host">
        <title>p4.host -&gt; aString</title>

        <para>
          Get the current hostname.
        </para>

<programlisting language="ruby">
p4 = P4.new
puts( p4.host )
</programlisting>
      </section>

      <section xml:id="ruby.p4.input.eq">
        <title>p4.input= ( aString|aHash|anArray ) -&gt; aString|aHash|anArray</title>

        <para>
          Store input for the next command.
        </para>

        <para>
          Call this method prior to running a command requiring input from the
          user. When the command requests input, the specified data will be
          supplied to the command. Typically, commands of the form <command>p4
          <replaceable>cmd</replaceable> -i</command> are invoked using the
          <methodname>P4#save_<replaceable>&lt;spectype&gt;</replaceable>()</methodname>
          methods, which call <methodname>P4#input()</methodname> internally;
          there is no need to call <methodname>P4#input()</methodname> when
          using the
          <methodname>P4#save_<replaceable>&lt;spectype&gt;</replaceable>()</methodname>
          shortcuts.
        </para>

        <para>
          You may pass a string, a hash, or (for commands that take multiple
          inputs from the user) an array of strings or hashes. If you pass an
          array, note that the array will be shifted each time Perforce asks the
          user for input.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.connect

change = p4.run_change( "-o" ).shift
change[ "Description" ] = "Autosubmitted changelist"

p4.input = change
p4.run_submit( "-i" )

p4.disconnect
</programlisting>
      </section>

      <section xml:id="ruby.p4.maxlocktime.eq">
        <title>p4.maxlocktime= anInteger -&gt; anInteger</title>

        <para>
          Limit the amount of time (in milliseconds) spent during data scans to
          prevent the server from locking tables for too long. Commands that
          take longer than the limit will be aborted. The limit remains in force
          until you disable it by setting it to zero.  See <command>p4 help
          maxlocktime</command> for information on the commands that support
          this limit.
        </para>

<programlisting language="ruby">
p4 = P4.new
begin
  p4.connect
  p4.maxlocktime = 10000 # 10 seconds
  files = p4.run_sync
rescue P4Exception => ex
  p4.errors.each { |e| $stderr.puts( e ) }
ensure
  p4.disconnectend
</programlisting>
      </section>

      <section xml:id="ruby.p4.maxlocktime">
        <title>p4.maxlocktime -&gt; anInteger</title>

        <para>
          Get the current <literal>maxlocktime</literal> setting.
        </para>

<programlisting language="ruby">
p4 = P4.new
puts( p4.maxlocktime )
</programlisting>
      </section>

      <section xml:id="ruby.p4.maxresults.eq">
        <title>p4.maxresults= anInteger -&gt; anInteger</title>

        <para>
          Limit the number of results Perforce permits for subsequent commands.
          Commands that produce more than this number of results will be
          aborted. The limit remains in force until you disable it by setting it
          to zero. See <command>p4 help maxresults</command> for information on
          the commands that support this limit.
        </para>

<programlisting language="ruby">
p4 = P4.new
begin
  p4.connect
  p4.maxresults = 100
  files = p4.run_sync
rescue P4Exception => ex
  p4.errors.each { |e| $stderr.puts( e ) }
ensure
  p4.disconnect
end
</programlisting>
      </section>

      <section xml:id="ruby.p4.maxresults">
        <title>p4.maxresults -&gt; anInteger</title>

        <para>
          Get the current <literal>maxresults</literal> setting.
        </para>

<programlisting language="ruby">
p4 = P4.new
puts( p4.maxresults )
</programlisting>
      </section>

      <section xml:id="ruby.p4.maxscanrows.eq">
        <title>p4.maxscanrows= anInteger -&gt; anInteger</title>

        <para>
          Limit the number of database records Perforce will scan for subsequent
          commands. Commands that attempt to scan more than this number of
          records will be aborted. The limit remains in force until you disable
          it by setting it to zero. See <command>p4 help maxscanrows</command>
          for information on the commands that support this limit.
        </para>

<programlisting language="ruby">
p4 = P4.new
begin
  p4.connect
  p4.maxscanrows = 100
  files = p4.run_sync
rescue P4Exception => ex
  p4.errors.each { |e| $stderr.puts( e ) }
ensure
  p4.disconnectend
</programlisting>
      </section>

      <section xml:id="ruby.p4.maxscanrows">
        <title>p4.maxscanrows -&gt; anInteger</title>

        <para>
          Get the current <literal>maxscanrows</literal> setting.
        </para>

<programlisting language="ruby">
p4 = P4.new
puts( p4.maxscanrows )
</programlisting>
      </section>

      <section xml:id="ruby.p4.messages">
        <title>p4.messages -&gt; aP4::Message</title>

        <para>
          Returns a message from the Perforce Server in the form of a
          <classname>P4::Message</classname> object.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.exception_level = P4::RAISE_NONE
p4.run_sync
p4.run_sync    # this second sync should return "File(s) up-to-date."
w = p4.messages[0]
puts ( w.to_s )
</programlisting>
      </section>

      <section xml:id="ruby.p4.p4config_file">
        <title>p4.p4config_file -&gt; aString</title>

        <para>
          Get the path to the current <envar>P4CONFIG</envar> file.
        </para>

<programlisting language="ruby">
p4 = P4.new
puts( p4.p4config_file )
</programlisting>
      </section>

      <section xml:id="ruby.p4.parse_spectype">
        <title>p4.parse_&lt;spectype&gt;( aString ) -&gt; aP4::Spec</title>

        <para>
          This is equivalent to:
        </para>

<programlisting language="ruby">
p4.parse_spec( "<replaceable>&lt;spectype&gt;</replaceable>", aString )
</programlisting>
      </section>

      <section xml:id="ruby.p4.parse_spec">
        <title>p4.parse_spec( "&lt;spectype&gt;", aString ) -&gt; aP4::Spec</title>

        <para>
          Parses a Perforce form (spec) in text form into a Ruby hash using the
          spec definition obtained from the server.
        </para>

        <para>
          The first argument is the type of spec to parse:
          <literal>client</literal>, <literal>branch</literal>,
          <literal>label</literal>, and so on. The second argument is the string
          buffer to parse.
        </para>

        <para>
          Note that there are shortcuts available for this method. You can use:
        </para>

<programlisting language="ruby">
p4.parse_<replaceable>&lt;spectype&gt;</replaceable>( buf )
</programlisting>

        <para>
          instead of:
        </para>

<programlisting language="ruby">
p4.parse_spec( "<replaceable>&lt;spectype&gt;</replaceable>", buf )
</programlisting>

        <para>
          Where <replaceable>&lt;spectype&gt;</replaceable> is one of
          <literal>client</literal>, <literal>branch</literal>,
          <literal>label</literal>, and so on.
        </para>
      </section>

      <section xml:id="ruby.p4.password.eq">
        <title>p4.password= aString -&gt; aString</title>

        <para>
          Set your Perforce password, in plain text. If not used, takes the
          value of <envar>P4PASSWD</envar> from any <envar>P4CONFIG</envar> file
          in effect, or from the environment according to the normal Perforce
          conventions. This password will also be used if you later call
          <methodname>p4.run_login</methodname> to login using the 2003.2 and later
          ticket system.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.password = "mypass"
p4.connect
p4.run_login
</programlisting>
      </section>

      <section xml:id="ruby.p4.password">
        <title>p4.password -&gt; aString</title>

        <para>
          Get the current password or ticket. This may be the password in plain
          text, or if you've used <methodname>P4#run_login()</methodname>, it'll
          be the value of the ticket you've been allocated by the server.
        </para>

<programlisting language="ruby">
p4 = P4.new
puts( p4.password )
</programlisting>
      </section>

      <section xml:id="ruby.p4.port.eq">
        <title>p4.port= aString -&gt; aString</title>

        <para>
          Set the host and port of the Perforce server you want to connect to.
          If not called, defaults to the value of <envar>P4PORT</envar> in any
          <envar>P4CONFIG</envar> file in effect, and then to the value of
          <envar>P4PORT</envar> taken from the environment.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.port = "localhost:1666"
p4.connect
...
p4.disconnect
</programlisting>
      </section>

      <section xml:id="ruby.p4.port">
        <title>p4.port -&gt; aString</title>

        <para>
          Get the host and port of the current Perforce server.
        </para>

<programlisting language="ruby">
p4 = P4.new
puts( p4.port )
</programlisting>
      </section>

      <section xml:id="ruby.p4.prog.eq">
        <title>p4.prog= aString -&gt; aString</title>

        <para>
          Set the name of the program, as reported to Perforce system
          administrators running <command>p4 monitor show -e</command> in
          Perforce 2004.2 or later releases.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.prog = "sync-script"
p4.connect
...
p4.disconnect
</programlisting>
      </section>

      <section xml:id="ruby.p4.prog">
        <title>p4.prog -&gt; aString</title>

        <para>
          Get the name of the program as reported to the Perforce Server.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.prog = "sync-script"
puts( p4.prog )
</programlisting>
      </section>

      <section xml:id="ruby.p4.progress.eq">
        <title>p4.progress= aProgress -&gt; aProgress</title>

        <para>
          Set the current progress indicator. This should be a subclass of
          <classname>P4::Progress</classname>.
        </para>
      </section>

      <section xml:id="ruby.p4.progress">
        <title>p4.progress -&gt; aProgress</title>

        <para>
          Get the current progress indicator.
        </para>
      </section>

      <section xml:id="ruby.p4.run_cmd">
        <title>p4.run_&lt;cmd&gt;( arguments ) -&gt; anArray</title>

        <para>
          This is equivalent to:
        </para>

<programlisting language="ruby">
p4.run( "<replaceable>cmd</replaceable>", arguments... )
</programlisting>
      </section>

      <section xml:id="ruby.p4.run">
        <title>p4.run( aCommand, arguments... ) -&gt; anArray</title>

        <para>
          Base interface to all the run methods in this API. Runs the specified
          Perforce command with the arguments supplied. Arguments may be in any
          form as long as they can be converted to strings by
          <literal>to_s</literal>.
        </para>

        <para>
          The <methodname>P4#run()</methodname> method returns an array of
          results whether the command succeeds or fails; the array may, however,
          be empty. Whether the elements of the array are strings or hashes
          depends on (a) server support for tagged output for the command, and
          (b) whether tagged output was disabled by calling <literal>p4.tagged =
          false</literal>.
        </para>

        <para>
          In the event of errors or warnings, and depending on the exception
          level in force at the time, <methodname>P4#run()</methodname> will
          raise a <exceptionname>P4Exception</exceptionname>. If the current
          exception level is below the threshold for the error/warning,
          <methodname>P4#run()</methodname> returns the output as normal and the
          caller must explicitly review <methodname>P4#errors()</methodname> and
          <methodname>P4#warnings()</methodname> to check for errors or
          warnings.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.connect
spec = p4.run( "client", "-o" ).shift
p4.disconnect
</programlisting>

        <para>
          Shortcuts are available for <methodname>P4#run()</methodname>. For
          example:
        </para>

<programlisting language="ruby">
p4.run_<replaceable>command</replaceable>( args )
</programlisting>

        <para>
          is equivalent to:
        </para>

<programlisting language="ruby">
p4.run( "<replaceable>command</replaceable>", args )
</programlisting>

        <para>
          There are also some shortcuts for common commands such as editing
          Perforce forms and submitting. Consequently, this:
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.connect
clientspec = p4.run_client( "-o" ).shift
clientspec[ "Description" ] = "Build client"
p4.input = clientspec
p4.run_client( "-i" )
p4.disconnect
</programlisting>

        <para>
          may be shortened to:
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.connect
clientspec = p4.fetch_client
clientspec[ "Description" ] = "Build client"
p4.save_client( clientspec )
p4.disconnect
</programlisting>

        <para>
          The following are equivalent:
        </para>

        <informaltable>
          <tgroup cols="2">
            <colspec colname="method" colwidth="*"/>
            <colspec colname="description" colwidth="3*"/>
            <tbody>
              <row>
                <entry>
                  <para>
                    <code>p4.delete_<replaceable>&lt;spectype&gt;</replaceable>()</code>
                  </para>
                </entry>

                <entry>
                  <para>
                    <code>p4.run( "<replaceable>&lt;spectype&gt;</replaceable>", "-d" )</code>
                  </para>
                </entry>
              </row>

              <row>
                <entry>
                  <para>
                    <code>p4.fetch_<replaceable>&lt;spectype&gt;</replaceable>()</code>
                  </para>
                </entry>

                <entry>
                  <para>
                    <code>p4.run( "<replaceable>&lt;spectype&gt;</replaceable>", "-o" ).shift</code>
                  </para>
                </entry>
              </row>

              <row>
                <entry>
                  <para>
                    <code>p4.save_<replaceable>&lt;spectype&gt;</replaceable>( spec )</code>
                  </para>
                </entry>

                <entry>
                  <para>
                    <code>p4.input = specp4.run( "<replaceable>&lt;spectype&gt;</replaceable>", "-i" )</code>
                  </para>
                </entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>
          As the commands associated with
          <methodname>P4#fetch_<replaceable>&lt;spectype&gt;</replaceable>()</methodname>
          typically return only one item, these methods do not return an array,
          but instead return the first result element.
        </para>

        <para>
          For convenience in submitting changelists, changes returned by
          <methodname>P4#fetch_change()</methodname> can be passed to
          <methodname>P4#run_submit</methodname>. For example:
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.connect
spec = p4.fetch_changespec[ "Description" ] = "Automated change"
p4.run_submit( spec )
p4.disconnect
</programlisting>
      </section>

      <section xml:id="ruby.p4.run_filelog">
        <title>p4.run_filelog( fileSpec ) -&gt; anArray</title>

        <para>
          Runs a <command>p4 filelog</command> on the
          <literal>fileSpec</literal> provided and returns an array of
          <classname>P4::DepotFile</classname> results when executed in tagged
          mode, and an array of strings when executed in non-tagged mode. By
          default, the raw output of <command>p4 filelog</command> is tagged;
          this method restructures the output into a more user-friendly (and
          object-oriented) form.
        </para>

<programlisting language="ruby">
p4 = P4.new
begin
  p4.connect
  p4.run_filelog( "index.html" ).shift.each_revision do
    |r|
    r.each_integration do
      |i|
      # Do something
    end
  end
rescue P4Exception
  p4.errors.each { |e| puts( e ) }
ensure
  p4.disconnect
end
</programlisting>
      </section>

      <section xml:id="ruby.p4.run_login">
        <title>p4.run_login( arg... ) -&gt; anArray</title>

        <para>
          Runs <command>p4 login</command> using a password or ticket set by the
          user.
        </para>
      </section>

      <section xml:id="ruby.p4.run_password">
        <title>p4.run_password( oldpass, newpass ) -&gt; anArray</title>

        <para>
          A thin wrapper to make it easy to change your password. This method is
          (literally) equivalent to the following code:
        </para>

<programlisting language="ruby">
p4.input( [ oldpass, newpass, newpass ] )
p4.run( "password" )
</programlisting>

        <para>
          For example:
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.password = "myoldpass"
begin
  p4.connect
  p4.run_password( "myoldpass", "mynewpass" )
rescue P4Exception
  p4.errors.each { |e| puts( e ) }
ensure
  p4.disconnect
end
</programlisting>
      </section>

      <section xml:id="ruby.p4.run_resolve">
        <title>p4.run_resolve( args ) [ block ] -&gt; anArray</title>

        <para>
          Interface to <command>p4 resolve</command>. Without a block, simply
          runs a non-interactive resolve (typically an automatic resolve).
        </para>

<programlisting language="ruby">
p4.run_resolve( "-at" )
</programlisting>

        <para>
          When a block is supplied, the block is invoked once for each merge
          scheduled by Perforce. For each merge, a
          <classname>P4::MergeData</classname> object is passed to the block.
          This object contains the context of the merge.
        </para>

        <para>
          The block determines the outcome of the merge by evaluating to one of
          the following strings:
        </para>

        <informaltable>
          <tgroup cols="2">
            <colspec colname="string" colwidth="*"/>
            <colspec colname="meaning" colwidth="6*"/>
            <thead>
              <row>
                <entry>
                  <para>
                    Block string
                  </para>
                </entry>

                <entry>
                  <para>
                    Meaning
                  </para>
                </entry>
              </row>
            </thead>

            <tbody>
              <row>
                <entry>
                  <para>
                    <literal>ay</literal>
                  </para>
                </entry>

                <entry>
                  <para>
                    Accept Yours.
                  </para>
                </entry>
              </row>

              <row>
                <entry>
                  <para>
                    <literal>at</literal>
                  </para>
                </entry>

                <entry>
                  <para>
                    Accept Theirs.
                  </para>
                </entry>
              </row>

              <row>
                <entry>
                  <para>
                    <literal>am</literal>
                  </para>
                </entry>

                <entry>
                  <para>
                    Accept Merge result.
                  </para>
                </entry>
              </row>

              <row>
                <entry>
                  <para>
                    <literal>ae</literal>
                  </para>
                </entry>

                <entry>
                  <para>
                    Accept Edited result.
                  </para>
                </entry>
              </row>

              <row>
                <entry>
                  <para>
                    <literal>s</literal>
                  </para>
                </entry>

                <entry>
                  <para>
                    Skip this merge.
                  </para>
                </entry>
              </row>

              <row>
                <entry>
                  <para>
                    <literal>q</literal>
                  </para>
                </entry>

                <entry>
                  <para>
                    Abort the merge.
                  </para>
                </entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>
          For example:
        </para>

<programlisting language="ruby">
p4.run_resolve() do
  |md|
  puts( "Merging..." )
  puts( "Yours: #{md.your_name}" )
  puts( "Theirs: #{md.their_name}" )
  puts( "Base: #{md.base_name}" )
  puts( "Yours file: #{md.your_path}" )
  puts( "Theirs file: #{md.their_path}" )
  puts( "Base file: #{md.base_path}" )
  puts( "Result file: #{md.result_path}" )
  puts( "Merge Hint: #{md.merge_hint}" )

  result = md.merge_hint
  if( result == "e" )
      puts( "Invoking external merge application" )
      result = "s"    # If the merge doesn't work, we'll skip
      result = "am" if md.run_merge()
  end
  result
end
</programlisting>
      </section>

      <section xml:id="ruby.p4.run_submit">
        <title>p4.run_submit( [aHash], [arg...] ) -&gt; anArray</title>

        <para>
          Submit a changelist to the server. To submit a changelist, set the
          fields of the changelist as required and supply any flags:.
        </para>

<programlisting language="ruby">
change = p4.fetch_change
change._description = "Some description"
p4.run_submit( "-r", change )
</programlisting>

        <para>
          You can also submit a changelist by supplying the arguments as you
          would on the command line:
        </para>

<programlisting language="ruby">
p4.run_submit( "-d", "Some description", "somedir/..." )
</programlisting>
      </section>

      <section xml:id="ruby.p4.run_tickets">
        <title>p4.run_tickets( ) -&gt; anArray</title>

        <para>
          Get a list of tickets from the local tickets file. Each ticket is a
          hash object with fields for <literal>Host</literal>,
          <literal>User</literal>, and <literal>Ticket</literal>.
        </para>
      </section>

      <section xml:id="ruby.p4.save_spectype">
        <title>p4.save_&lt;spectype&gt;( hashOrString, [options] ) -&gt; anArray</title>

        <para>
          The <methodname>save_<replaceable>&lt;spectype&gt;</replaceable></methodname>
          methods are shortcut methods that allow you to quickly update the
          definitions of clients, labels, branches, etc. They are equivalent to:
        </para>

<programlisting language="ruby">
p4.input = hashOrStringp4.run( "<replaceable>&lt;spectype&gt;</replaceable>", "-i" )
</programlisting>

        <para>
          For example:
        </para>

<programlisting language="ruby">
p4 = P4.new
begin
  p4.connect
  client            = p4.fetch_client()
  client[ "Owner" ] = p4.user
  p4.save_client( client )
rescue P4Exception
  p4.errors.each { |e| puts( e ) }
ensure
  p4.disconnect
end
</programlisting>
      </section>

      <section xml:id="ruby.p4.server_case_sensitive">
        <title>p4.server_case_sensitive? -&gt; aBool</title>

        <para>
          Detects whether or not the server is case-sensitive.
        </para>
      </section>

      <section xml:id="ruby.p4.server_level">
        <title>p4.server_level -&gt; anInteger</title>

        <para>
          Returns the current Perforce server level. Each iteration of the
          Perforce Server is given a level number. As part of the initial
          communication this value is passed between the client application and
          the Perforce Server. This value is used to determine the communication
          that the Perforce Server will understand. All subsequent requests can
          therefore be tailored to meet the requirements of this Server level.
        </para>

        <para>
          For more information, see:
        </para>

        <para>
          <link xlink:href="http://kb.perforce.com/article/571">http://kb.perforce.com/article/571</link>
        </para>
      </section>

      <section xml:id="ruby.p4.server_unicode">
        <title>p4.server_unicode? -&gt; aBool</title>

        <para>
          Detects whether or not the server is in unicode mode.
        </para>
      </section>

      <section xml:id="ruby.p4.set_env">
        <title>p4.set_env= ( aString, aString )  -&gt; aBool</title>

        <para>
          On Windows or OS X, set a variable in the registry or user
          preferences. To unset a variable, pass an empty string as the second
          argument. On other platforms, an exception is raised.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.set_env = ( "P4CLIENT", "my_workspace" )
p4.set_env = ( "P4CLIENT", "" )
</programlisting>
      </section>

      <section xml:id="ruby.p4.streams.eq">
        <title>p4.streams= -&gt; aBool</title>

        <para>
          Enable or disable support for streams. By default, streams support is
          enabled at 2011.1 or higher (<methodname>P4#api_level()</methodname>
          >= 70). Raises a <exceptionname>P4Exception</exceptionname> if you
          attempt to enable streams on a pre-2011.1 server. You can enable or
          disable support for streams both before and after connecting to the
          server.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.streams = false
</programlisting>
      </section>

      <section xml:id="ruby.p4.streams">
        <title>p4.streams? -&gt; aBool</title>

        <para>
          Detects whether or not support for Perforce Streams is enabled.
        </para>

<programlisting language="ruby">
p4 = P4.new
puts ( p4.streams? )
p4.tagged = false
puts ( p4.streams? )
</programlisting>
      </section>

      <section xml:id="ruby.p4.tagged">
        <title>p4.tagged( aBool ) { block }</title>

        <para>
          Temporarily toggles the use of tagged output for the duration of the
          block, and then resets it when the block terminates.
        </para>
      </section>

      <section xml:id="ruby.p4.tagged.eq">
        <title>p4.tagged= aBool -&gt; aBool</title>

        <para>
          Sets tagged output. By default, tagged output is on.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.tagged = false
</programlisting>
      </section>

      <section xml:id="ruby.p4.tagged.q">
        <title>p4.tagged? -&gt; aBool</title>

        <para>
          Detects whether or not you are in tagged mode.
        </para>

<programlisting language="ruby">
p4 = P4.new
puts ( p4.tagged? )
p4.tagged = false
puts ( p4.tagged? )
</programlisting>
      </section>

      <section xml:id="ruby.p4.ticketfile.eq">
        <title>p4.ticketfile= aString -&gt; aString</title>

        <para>
          Sets the location of the <envar>P4TICKETS</envar> file.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.ticketfile = "/home/bruno/tickets"
</programlisting>
      </section>

      <section xml:id="ruby.p4.ticketfile">
        <title>p4.ticketfile -&gt; aString</title>

        <para>
          Get the path to the current <envar>P4TICKETS</envar> file.
        </para>

<programlisting language="ruby">
p4 = P4.new
puts( p4.ticketfile )
</programlisting>
      </section>

      <section xml:id="ruby.p4.track.eq">
        <title>p4.track= -&gt; aBool</title>

        <para>
          Instruct the server to return messages containing performance tracking
          information. By default, server tracking is disabled.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.track = true
</programlisting>
      </section>

      <section xml:id="ruby.p4.track">
        <title>p4.track? -&gt; aBool</title>

        <para>
          Detects whether or not performance tracking is enabled.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.track = true
puts ( p4.track? )
p4.track = false
puts ( p4.track? )
</programlisting>
      </section>

      <section xml:id="ruby.p4.track_output">
        <title>p4.track_output -&gt; anArray</title>

        <para>
          If performance tracking is enabled with <literal>p4.track=</literal>,
          returns a list of strings corresponding to the performance tracking
          output for the most recently-executed command.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.track = true
p4.run_info
puts ( p4.track_output[0].slice(0,3) )   # should be "rpc"
</programlisting>
      </section>

      <section xml:id="ruby.p4.user.eq">
        <title>p4.user= aString -&gt; aString</title>

        <para>
          Set the Perforce username. If not called, defaults to the value of
          <envar>P4USER</envar> taken from any <envar>P4CONFIG</envar> file
          present, or from the environment as per the usual Perforce convention.
          Must be called before connecting to the Perforce server.
        </para>

<programlisting language="ruby">
p4 = P4.new
p4.user = "bruno"
p4.connect
...
p4.disconnect
</programlisting>
      </section>

      <section xml:id="ruby.p4.user">
        <title>p4.user -&gt; aString</title>

        <para>
          Returns the current Perforce username.
        </para>

<programlisting language="ruby">
p4 = P4.new
puts( p4.user )
</programlisting>
      </section>

      <section xml:id="ruby.p4.version.eq">
        <title>p4.version= aString -&gt; aString</title>

        <para>
          Set the version of your script, as reported to the Perforce Server.
        </para>
      </section>

      <section xml:id="ruby.p4.version">
        <title>p4.version -&gt; aString</title>

        <para>
          Get the version of your script, as reported to the Perforce Server.
        </para>
      </section>

      <section xml:id="ruby.p4.warnings">
        <title>p4.warnings -&gt; anArray</title>

        <para>
          Returns the array of warnings that arose during execution of the last
          command.
        </para>

<programlisting language="ruby">
p4 = P4.new
begin
  p4.connect
  p4.exception_level( P4::RAISE_ALL ) # File(s) up-to-date is a warning
  files = p4.run_sync
rescue P4Exception => ex
  p4.warnings.each { |w| puts( w ) }
ensure
  p4.disconnect
end
</programlisting>
      </section>
    </section>
  </chapter>

  <chapter xml:id="ruby.p4_exception">
    <title>Class P4Exception</title>

    <para>
      Shallow subclass of <exceptionname>RuntimeError</exceptionname> to be used
      for catching Perforce-specific errors. Doesn't contain any extra
      information. See <methodname>P4#errors()</methodname> and
      <methodname>P4#warnings</methodname> for details of the errors giving rise
      to the exception.
    </para>

    <section xml:id="ruby.p4_exception-class_methods">
      <title>Class Methods</title>

      <para>
        None.
      </para>
    </section>

    <section xml:id="ruby.p4_exception-instance_methods">
      <title>Instance Methods</title>

      <para>
        None.
      </para>
    </section>
  </chapter>

  <chapter xml:id="ruby.p4_depotfile">
    <title>Class P4::DepotFile</title>

    <section xml:id="ruby.p4_depotfile-description">
      <title>Description</title>

      <para>
        Utility class providing easy access to the attributes of a file in a
        Perforce depot. Each <classname>P4::DepotFile</classname> object contains
        summary information about the file, and a list of revisions
        (<classname>P4::Revision</classname> objects) of that file. Currently,
        only the <methodname>P4#run_filelog()</methodname> method returns an
        array of <classname>P4::DepotFile</classname> objects.
      </para>
    </section>

    <section xml:id="ruby.p4_depotfile-class_methods">
      <title>Class Methods</title>

      <para>
        None.
      </para>
    </section>

    <section xml:id="ruby.p4_depotfile-instance_methods">
      <title>Instance Methods</title>

      <section xml:id="ruby.p4_depotfile.depot_file">
        <title>df.depot_file -&gt; aString</title>

        <para>
          Returns the name of the depot file to which this object refers.
        </para>
      </section>

      <section xml:id="ruby.p4_depotfile.each_revision">
        <title>df.each_revision { |rev| block } -&gt; revArray</title>

        <para>
          Iterates over each revision of the depot file.
        </para>
      </section>

      <section xml:id="ruby.p4_depotfile.revisions">
        <title>df.revisions -&gt; aArray</title>

        <para>
          Returns an array of revisions of the depot file.
        </para>
      </section>
    </section>
  </chapter>

  <chapter xml:id="ruby.p4_revision">
    <title>Class P4::Revision</title>

    <section xml:id="ruby.p4_revision-description">
      <title>Description</title>

      <para>
        Utility class providing easy access to the revisions of a file in a
        Perforce depot. <classname>P4::Revision</classname> objects can store basic
        information about revisions and a list of the integrations for that
        revision. Created by <methodname>P4#run_filelog()</methodname>.
      </para>
    </section>

    <section xml:id="ruby.p4_revision-class_methods">
      <title>Class Methods</title>

      <para>
        None.
      </para>
    </section>

    <section xml:id="ruby.p4_revision-instance_methods">
      <title>Instance Methods</title>

      <section xml:id="ruby.p4_revision.action">
        <title>rev.action -&gt; aString</title>

        <para>
          Returns the name of the action which gave rise to this revision of the
          file.
        </para>
      </section>

      <section xml:id="ruby.p4_revision.change">
        <title>rev.change -&gt; aNumber</title>

        <para>
          Returns the change number that gave rise to this revision of the file.
        </para>
      </section>

      <section xml:id="ruby.p4_revision.client">
        <title>rev.client -&gt; aString</title>

        <para>
          Returns the name of the client from which this revision was submitted.
        </para>
      </section>

      <section xml:id="ruby.p4_revision.depot_file">
        <title>rev.depot_file -&gt; aString</title>

        <para>
          Returns the name of the depot file to which this object refers.
        </para>
      </section>

      <section xml:id="ruby.p4_revision.desc">
        <title>rev.desc -&gt; aString</title>

        <para>
          Returns the description of the change which created this revision.
          Note that only the first 31 characters are returned unless you use
          <command>p4 filelog -L</command> for the first 250 characters, or
          <command>p4 filelog -l</command> for the full text.
        </para>
      </section>

      <section xml:id="ruby.p4_revision.digest">
        <title>rev.digest -&gt; aString</title>

        <para>
          Returns the MD5 digest for this revision of the file.
        </para>
      </section>

      <section xml:id="ruby.p4_revision.each_integration">
        <title>rev.each_integration { |integ| block } -&gt; integArray</title>

        <para>
          Iterates over each the integration records for this revision of the
          depot file.
        </para>
      </section>

      <section xml:id="ruby.p4_revision.filesize">
        <title>rev.filesize -&gt; aNumber</title>

        <para>
          Returns size of this revision.
        </para>
      </section>

      <section xml:id="ruby.p4_revision.integrations">
        <title>rev.integrations -&gt; integArray</title>

        <para>
          Returns the list of integrations for this revision.
        </para>
      </section>

      <section xml:id="ruby.p4_revision.rev">
        <title>rev.rev -&gt; aNumber</title>

        <para>
          Returns the number of this revision of the file.
        </para>
      </section>

      <section xml:id="ruby.p4_revision.time">
        <title>rev.time -&gt; aTime</title>

        <para>
          Returns the date/time that this revision was created.
        </para>
      </section>

      <section xml:id="ruby.p4_revision.type">
        <title>rev.type -&gt; aString</title>

        <para>
          Returns this revision's Perforce filetype.
        </para>
      </section>

      <section xml:id="ruby.p4_revision.user">
        <title>rev.user -&gt; aString</title>

        <para>
          Returns the name of the user who created this revision.
        </para>
      </section>
    </section>
  </chapter>

  <chapter xml:id="ruby.p4_integration">
    <title>Class P4::Integration</title>

    <section xml:id="ruby.p4_integration-description">
      <title>Description</title>

      <para>
        Utility class providing easy access to the details of an integration
        record. Created by <methodname>P4#run_filelog()</methodname>.
      </para>
    </section>

    <section xml:id="ruby.p4_integration-class_methods">
      <title>Class Methods</title>

      <para>
        None.
      </para>
    </section>

    <section xml:id="ruby.p4_integration-instance_methods">
      <title>Instance Methods</title>

      <section xml:id="ruby.p4_integration.how">
        <title>integ.how -&gt; aString</title>

        <para>
          Returns the type of the integration record - how that record was
          created.
        </para>
      </section>

      <section xml:id="ruby.p4_integration.file">
        <title>integ.file -&gt; aPath</title>

        <para>
          Returns the path to the file being integrated to/from.
        </para>
      </section>

      <section xml:id="ruby.p4_integration.srev">
        <title>integ.srev -&gt; aNumber</title>

        <para>
          Returns the start revision number used for this integration.
        </para>
      </section>

      <section xml:id="ruby.p4_integration.erev">
        <title>integ.erev -&gt; aNumber</title>

        <para>
          Returns the end revision number used for this integration.
        </para>
      </section>
    </section>
  </chapter>

  <chapter xml:id="ruby.p4_map">
    <title>Class P4::Map</title>

    <section xml:id="ruby.p4_map-description">
      <title>Description</title>

      <para>
        The <classname>P4::Map</classname> class allows users to create and work
        with Perforce mappings, without requiring a connection to a Perforce
        server.
      </para>
    </section>

    <section xml:id="ruby.p4_map-class_methods">
      <title>Class Methods</title>

      <section xml:id="ruby.p4_map.new">
        <title>Map.new ( [ anArray ] ) -&gt; aMap</title>

        <para>
          Constructs a new <classname>P4::Map</classname> object.
        </para>
      </section>

      <section xml:id="ruby.p4_map.join">
        <title>Map.join ( map1, map2 ) -&gt; aMap</title>

        <para>
          Join two <classname>P4::Map</classname> objects and create a third.
        </para>

        <para>
          The new map is composed of the left-hand side of the first mapping, as
          joined to the right-hand side of the second mapping. For example:
        </para>

<programlisting language="ruby">
# Map depot syntax to client syntax
client_map = P4::Map.new
client_map.insert( "//depot/main/...", "//client/..." )

# Map client syntax to local syntax
client_root = P4::Map.new
client_root.insert( "//client/...", "/home/bruno/workspace/..." )

# Join the previous mappings to map depot syntax to local syntax
local_map = P4::Map.join( client_map, client_root )
local_path = local_map.translate( "//depot/main/www/index.html" )

# local_path is now /home/bruno/workspace/www/index.html
</programlisting>
      </section>
    </section>

    <section xml:id="ruby.p4_map-instance_methods">
      <title>Instance Methods</title>

      <section xml:id="ruby.p4_map.clear">
        <title>map.clear -&gt; true</title>

        <para>
          Empty a map.
        </para>
      </section>

      <section xml:id="ruby.p4_map.count">
        <title>map.count -&gt; anInteger</title>

        <para>
          Return the number of entries in a map.
        </para>
      </section>

      <section xml:id="ruby.p4_map.empty">
        <title>map.empty? -&gt; aBool</title>

        <para>
          Test whether a map object is empty.
        </para>
      </section>

      <section xml:id="ruby.p4_map.insert">
        <title>map.insert( aString, [ aString ] ) -&gt; aMap</title>

        <para>
          Inserts an entry into the map.
        </para>

        <para>
          May be called with one or two arguments. If called with one argument,
          the string is assumed to be a string containing either a half-map, or
          a string containing both halves of the mapping. In this form, mappings
          with embedded spaces must be quoted. If called with two arguments,
          each argument is assumed to be half of the mapping, and quotes are
          optional.
        </para>

<programlisting language="ruby">
# called with two arguments:
map.insert( "//depot/main/...", "//client/..." )

# called with one argument containing both halves of the mapping:
map.insert( "//depot/live/... //client/live/..." )

# called with one argument containing a half-map:
# This call produces the mapping "depot/... depot/..."
map.insert( "depot/..." )
</programlisting>
      </section>

      <section xml:id="ruby.p4_map.translate">
        <title>map.translate ( aString, [ aBool ] )-> aString</title>

        <para>
          Translate a string through a map, and return the result. If the
          optional second argument is true, translate forward, and if it is
          false, translate in the reverse direction. By default, translation is
          in the forward direction.
        </para>
      </section>

      <section xml:id="ruby.p4_map.includes">
        <title>map.includes? ( aString ) -&gt; aBool</title>

        <para>
          Tests whether a path is mapped or not.
        </para>

<programlisting language="ruby">
if( map.includes?( "//depot/main/..." ) )
  ...
end
</programlisting>
      </section>

      <section xml:id="ruby.p4_map.reverse">
        <title>map.reverse -&gt; aMap</title>

        <para>
          Return a new <classname>P4::Map</classname> object with the left and
          right sides of the mapping swapped. The original object is unchanged.
        </para>
      </section>

      <section xml:id="ruby.p4_map.lhs">
        <title>map.lhs -&gt; anArray</title>

        <para>
          Returns the left side of a mapping as an array.
        </para>
      </section>

      <section xml:id="ruby.p4_map.rhs">
        <title>map.rhs -&gt; anArray</title>
        <para>
          Returns the right side of a mapping as an array.
        </para>
      </section>

      <section xml:id="ruby.p4_map.to_a">
        <title>map.to_a -&gt; anArray</title>

        <para>
          Returns the map as an array.
        </para>
      </section>
    </section>
  </chapter>

  <chapter xml:id="ruby.p4_mergedata">
    <title>Class P4::MergeData</title>

    <section xml:id="ruby.p4_mergedata-description">
      <title>Description</title>

      <para>
        Class containing the context for an individual merge during execution of
        a <command>p4 resolve</command>.
      </para>
    </section>

    <section xml:id="ruby.p4_mergedata-class_methods">
      <title>Class Methods</title>

      <para>
        None.
      </para>
    </section>

    <section xml:id="ruby.p4_mergedata-instance_methods">
      <title>Instance Methods</title>

      <section xml:id="ruby.p4_mergedata.your_name">
        <title>md.your_name() -&gt; aString</title>

        <para>
          Returns the name of "your" file in the merge. This is typically a path
          to a file in the workspace.
        </para>

<programlisting language="ruby">
p4.run_resolve() do
  |md|
  yours = md.your_name
  md.merge_hint # merge result
end
</programlisting>
      </section>

      <section xml:id="ruby.p4_mergedata.their_name">
        <title>md.their_name() -&gt; aString</title>

        <para>
          Returns the name of "their" file in the merge. This is typically a
          path to a file in the depot.
        </para>

<programlisting language="ruby">
p4.run_resolve() do
  |md|
  theirs = md.their_name
  md.merge_hint # merge result
end
</programlisting>
      </section>

      <section xml:id="ruby.p4_mergedata.base_name">
        <title>md.base_name() -&gt; aString</title>

        <para>
          Returns the name of the "base" file in the merge. This is typically a
          path to a file in the depot.
        </para>

<programlisting language="ruby">
p4.run_resolve() do
  |md|
  base = md.base_name
  md.merge_hint # merge result
end
</programlisting>
      </section>

      <section xml:id="ruby.p4_mergedata.your_path">
        <title>md.your_path() -&gt; aString</title>

        <para>
          Returns the path of "your" file in the merge. This is typically a path
          to a file in the workspace.
        </para>

<programlisting language="ruby">
p4.run_resolve() do
  |md|
  your_path = md.your_path
  md.merge_hint # merge result
end
</programlisting>
      </section>

      <section xml:id="ruby.p4_mergedata.their_path">
        <title>md.their_path() -&gt; aString</title>

        <para>
          Returns the path of "their" file in the merge. This is typically a
          path to a temporary file on your local machine in which the contents
          of <methodname>P4::MergeData#their_name()</methodname> have been
          loaded.
        </para>

<programlisting language="ruby">
p4.run_resolve() do
  |md|
  their_name = md.their_name
  their_file = File.open( md.their_path )
  md.merge_hint # merge result
end
</programlisting>
      </section>

      <section xml:id="ruby.p4_mergedata.base_path">
        <title>md.base_path() -&gt; aString</title>

        <para>
          Returns the path of the base file in the merge. This is typically a
          path to a temporary file on your local machine in which the contents
          of <methodname>P4::MergeData#base_name()</methodname> have been
          loaded.
        </para>

<programlisting language="ruby">
p4.run_resolve() do
  |md|
  base_name = md.base_name
  base_file = File.open( md.base_path )
  md.merge_hint # merge result
end
</programlisting>
      </section>

      <section xml:id="ruby.p4_mergedata.result_path">
        <title>md.result_path() -&gt; aString</title>

        <para>
          Returns the path to the merge result. This is typically a path to a
          temporary file on your local machine in which the contents of the
          automatic merge performed by the server have been loaded.
        </para>

<programlisting language="ruby">
p4.run_resolve() do
  |md|
  result_file = File.open( md.result_path )
  md.merge_hint # merge resultend
</programlisting>
      </section>

      <section xml:id="ruby.p4_mergedata.merge_hint">
        <title>md.merge_hint() -&gt; aString</title>

        <para>
          Returns the hint from the server as to how it thinks you might best
          resolve this merge.
        </para>

<programlisting language="ruby">
p4.run_resolve() do
  |md|
  puts ( md.merge_hint ) # merge result
end
</programlisting>
      </section>

      <section xml:id="ruby.p4_mergedata.run_merge">
        <title>md.run_merge() -&gt; aBool</title>

        <para>
          If the environment variable <envar>P4MERGE</envar> is defined,
          <methodname>P4::MergeData#run_merge()</methodname> invokes the
          specified program and returns a boolean based on the return value of
          that program.
        </para>

<programlisting language="ruby">
p4.run_resolve() do
  |md|
  if ( md.run_merge() )
    "am"
  else
    "s"
  end
end
</programlisting>
      </section>
    </section>
  </chapter>

  <chapter xml:id="ruby.p4_message">
    <title>Class P4::Message</title>

    <section xml:id="ruby.p4_message-description">
      <title>Description</title>

      <para>
        <classname>P4::Message</classname> objects contain error or other
        diagnostic messages from the Perforce Server; retrieve them by using the
        <methodname>P4#messages()</methodname> method.
      </para>

      <para>
        Script writers can test the severity of the messages in order to
        determine if the server message consisted of command output
        (<literal>E_INFO</literal>), warnings, (<literal>E_WARN</literal>), or
        errors (<literal>E_FAILED</literal>/<literal>E_FATAL</literal>).
      </para>
    </section>

    <section xml:id="ruby.p4_message-class_methods">
      <title>Class methods</title>

      <para>
        None.
      </para>
    </section>

    <section xml:id="ruby.p4_message-instance_methods">
      <title>Instance methods</title>

      <section xml:id="ruby.p4_message.severity">
        <title>message.severity() -&gt; anInteger</title>

        <para>
          Severity of the message, which is one of the following values:
        </para>

        <informaltable>
          <tgroup cols="2">
            <colspec colname="method" colwidth="*"/>
            <colspec colname="description" colwidth="5*"/>
            <thead>
              <row>
                <entry>
                  <para>
                    Value
                  </para>
                </entry>

                <entry>
                  <para>
                    Meaning
                  </para>
                </entry>
              </row>
            </thead>

            <tbody>
              <row>
                <entry>
                  <para>
                    <literal>E_EMPTY</literal>
                  </para>
                </entry>

                <entry>
                  <para>
                    No error
                  </para>
                </entry>
              </row>

              <row>
                <entry>
                  <para>
                    <literal>E_INFO</literal>
                  </para>
                </entry>

                <entry>
                  <para>
                    Informational message only
                  </para>
                </entry>
              </row>

              <row>
                <entry>
                  <para>
                    <literal>E_WARN</literal>
                  </para>
                </entry>

                <entry>
                  <para>
                    Warning message only
                  </para>
                </entry>
              </row>

              <row>
                <entry>
                  <para>
                    <literal>E_FAILED</literal>
                  </para>
                </entry>

                <entry>
                  <para>
                    Command failed
                  </para>
                </entry>
              </row>

              <row>
                <entry>
                  <para>
                    <literal>E_FATAL</literal>
                  </para>
                </entry>

                <entry>
                  <para>
                    Severe error; cannot continue.
                  </para>
                </entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
      </section>

      <section xml:id="ruby.p4_message.generic">
        <title>message.generic() -&gt; anInteger</title>

        <para>
          Returns the generic class of the error.
        </para>
      </section>

      <section xml:id="ruby.p4_message.msgid">
        <title>message.msgid() -&gt; anInteger</title>

        <para>
          Returns the unique ID of the message.
        </para>
      </section>

      <section xml:id="ruby.p4_message.to_s">
        <title>message.to_s() -&gt; aString</title>

        <para>
          Converts the message into a string.
        </para>
      </section>

      <section xml:id="ruby.p4_message.inspect">
        <title>message.inspect() -&gt; aString</title>

        <para>
          To facilitate debugging, returns a string that holds a formatted
          representation of the entire <classname>P4::Message</classname>
          object.
        </para>
      </section>
    </section>
  </chapter>

  <chapter xml:id="ruby.p4_outputhandler">
    <title>Class P4::OutputHandler</title>

    <section xml:id="ruby.p4_outputhandler-description">
      <title>Description</title>

      <para>
        The <classname>P4::OutputHandler</classname> class is a handler class
        that provides access to streaming output from the server. After defining
        the output handler, set <methodname>P4#handler()</methodname> to an
        instance of a subclass of <classname>P4::OutputHandler</classname> (or
        use a <literal>p4.with_handler( handler )</literal> block) to enable
        callbacks.
      </para>

      <para>
        By default, <classname>P4::OutputHandler</classname> returns
        <literal>P4::REPORT</literal> for all output methods. The different
        return options are:
      </para>

      <informaltable>
        <tgroup cols="2">
          <colspec colname="method" colwidth="*"/>
          <colspec colname="description" colwidth="4*"/>
          <thead>
            <row>
              <entry>
                <para>
                  Value
                </para>
              </entry>

              <entry>
                <para>
                  Meaning
                </para>
              </entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>
                <para>
                  <literal>P4::REPORT</literal>
                </para>
              </entry>

              <entry>
                <para>
                  Messages added to output.
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <literal>P4::HANDLED</literal>
                </para>
              </entry>

              <entry>
                <para>
                  Output is handled by class (don't add message to output).
                </para>
              </entry>
            </row>

            <row>
              <entry>
                <para>
                  <literal>P4::CANCEL</literal>
                </para>
              </entry>

              <entry>
                <para>
                  Operation is marked for cancel, message is added to output.
                </para>
              </entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
    </section>

    <section xml:id="ruby.p4_outputhandler-class_methods">
      <title>Class Methods</title>

      <section xml:id="ruby.p4_outputhandler.new">
        <title>new P4::MyHandler.new -&gt; aP4::OutputHandler</title>

        <para>
          Constructs a new subclass of <classname>P4::OutputHandler</classname>.
        </para>
      </section>
    </section>

    <section xml:id="ruby.p4_outputhandler-instance_methods">
      <title>Instance Methods</title>

      <section xml:id="ruby.p4_outputhandler.outputbinary">
        <title>outputBinary -&gt; int</title>

        <para>
          Process binary data.
        </para>
      </section>

      <section xml:id="ruby.p4_outputhandler.outputinfo">
        <title>outputInfo -&gt; int</title>

        <para>
          Process tabular data.
        </para>
      </section>

      <section xml:id="ruby.p4_outputhandler.outputmessage">
        <title>outputMessage -&gt; int</title>

        <para>
          Process informational or error messages.
        </para>
      </section>

      <section xml:id="ruby.p4_outputhandler.outputstat">
        <title>outputStat -&gt; int</title>

        <para>
          Process tagged data.
        </para>
      </section>

      <section xml:id="ruby.p4_outputhandler.outputtext">
        <title>outputText -&gt; int</title>

        <para>
          Process text data.
        </para>
      </section>
    </section>
  </chapter>

  <chapter xml:id="ruby.p4_progress">
    <title>Class P4::Progress</title>

    <section xml:id="ruby.p4_progress-description">
      <title>Description</title>

      <para>
        The <classname>P4::Progress</classname> class is a handler class that
        provides access to progress indicators from the server. After defining
        the output handler, set <methodname>P4#progress()</methodname> to an
        instance of a subclass of <classname>P4::Progress</classname> (or use a
        <literal>p4.with_progress( progress )</literal> block) to enable
        callbacks.
      </para>

      <para>
        You must implement all five of the following methods:
        <methodname>init()</methodname>, <methodname>description()</methodname>,
        <methodname>update()</methodname>, <methodname>total()</methodname>, and
        <methodname>done()</methodname>, even if the implementation consists of
        trivially returning <literal>0</literal>.
      </para>
    </section>

    <section xml:id="ruby.p4_progress-class_methods">
      <title>Class Methods</title>

      <section xml:id="ruby.p4_progress.new">
        <title>new P4::MyProgress.new -&gt; aP4::Progress</title>

        <para>
          Constructs a new subclass of <classname>P4::Progress</classname>.
        </para>
      </section>
    </section>

    <section xml:id="ruby.p4_progress-instance_methods">
      <title>Instance Methods</title>

      <section xml:id="ruby.p4_progress.init">
        <title>init -&gt; int</title>

        <para>
          Initialize progress indicator.
        </para>
      </section>

      <section xml:id="ruby.p4_progress.description">
        <title>description -&gt; int</title>

        <para>
          Description and type of units to be used for progress reporting.
        </para>
      </section>

      <section xml:id="ruby.p4_progress.update">
        <title>update -&gt; int</title>

        <para>
          If non-zero, user has requested a cancellation of the operation.
        </para>
      </section>

      <section xml:id="ruby.p4_progress.total">
        <title>total -&gt; int</title>

        <para>
          Total number of units expected (if known).
        </para>
      </section>

      <section xml:id="ruby.p4_progress.done">
        <title>done -&gt; int</title>

        <para>
          If non-zero, operation has failed.
        </para>
      </section>
    </section>
  </chapter>

  <chapter xml:id="ruby.p4_spec">
    <title>Class P4::Spec</title>

    <section xml:id="ruby.p4_spec-description">

      <title>Description</title>

      <para>
        The <classname>P4::Spec</classname> class is a hash containing key/value
        pairs for all the fields in a Perforce form. It provides two things over
        and above its parent class (Hash):
      </para>

      <itemizedlist>
        <listitem>
          <para>
            Fieldname validation. Only valid field names may be set in a
            <classname>P4::Spec</classname> object. Note that only the field
            name is validated, not the content.
          </para>
        </listitem>

        <listitem>
          <para>
            Accessor methods for easy access to the fields.
          </para>
        </listitem>
      </itemizedlist>
    </section>

    <section xml:id="ruby.p4_spec-class_methods">
      <title>Class Methods</title>

      <section xml:id="ruby.p4_spec.new">
        <title>new P4::Spec.new( anArray ) -&gt; aP4::Spec</title>

        <para>
          Constructs a new <classname>P4::Spec</classname> object given an array
          of valid fieldnames.
        </para>
      </section>
    </section>

    <section xml:id="ruby.p4_spec-instance_methods">
      <title>Instance Methods</title>

      <section xml:id="ruby.p4_spec._fieldname">
        <title>spec._&lt;fieldname&gt; -&gt; aValue</title>

        <para>
          Returns the value associated with the field named
          <replaceable>&lt;fieldname&gt;</replaceable>. This is equivalent to
          <code>spec[ "&lt;<replaceable>fieldname</replaceable>&gt;" ]</code>
          with the exception that when used as a method, the fieldnames may be
          in lowercase regardless of the actual case of the fieldname.
        </para>

<programlisting language="ruby">
client = p4.fetch_client()
root   = client._root
desc   = client._description
</programlisting>
      </section>

      <section xml:id="ruby.p4_spec._fieldname.eq">
        <title>spec._&lt;fieldname&gt;= aValue -&gt; aValue</title>

        <para>
          Updates the value of the named field in the spec. Raises a
          <exceptionname>P4Exception</exceptionname> if the fieldname is not
          valid for specs of this type.
        </para>

<programlisting language="ruby">
client               = p4.fetch_client()
client._root         = "/home/bruno/new-client"
client._description  = "My new client spec"
p4.save_client( client )
</programlisting>
      </section>

      <section xml:id="ruby.p4_spec.permitted_fields">
        <title>spec.permitted_fields -&gt; anArray</title>

        <para>
          Returns an array containing the names of fields that are valid in this
          spec object. This does not imply that values for all of these fields
          are actually set in this object, merely that you may choose to set
          values for any of these fields if you want to.
        </para>

<programlisting language="ruby">
client = p4.fetch_client()
spec.permitted_fields.each do
  | field |
  printf ( "%14s = %s\n", field, client[ field ] )
end
</programlisting>
      </section>
    </section>
  </chapter>

  <xi:include href="aa_license.xml" />

</book>
# Change User Description Committed
#2 14695 tjuricek Restructure the p4ruby docbook source to allow for a standalone HTML site, and update installation notes.

Removed obsolete framemaker files.

P4RUBY-173

Imported from Git
 Author: Tristan Juricek <[email protected]> 1418335025 -0800
 Committer: Tristan Juricek <[email protected]> 1418335025 -0800
 sha1: d772f6517f080ed1b5969c8954e7c7431449969d
 push-state: complete
 parent-changes: 141f8b9f65b4c56ce5a42144d8c185285effaa12=[974373]
#1 14682 Git Fusion Git Fusion branch management

Imported from Git
 ghost-of-change-num: 960958
 ghost-of-sha1: 005052ae424bd69f426f7209e741ca1c8c3253c7
 ghost-precedes-sha1: ad052c71a568ef12165e143a6866ad9ceffbb4a1
 parent-branch: None@960958
 push-state: incomplete