= Ruby Extensions Project README

== Table of Contents

1. Introduction
2. Sample Code
3. Links
4. Current Version and Status
5. Installation
6. What's Included?
7. Usage Information
8. Technical Information
9. Feedback
10. Licence


== Introduction

This project contains several extensions to the Ruby standard classes.  Many are
sourced from the Ruby Wiki (see links at end of document).

Criteria for inclusion of a method are:
- the method serves a general purpose
- it is reasonably clear from the method name what its behaviour is
- it would not generally be out of place in the language itself

Apart from convenience, the benefit of this package is to provide a reference.
You can use this package for your convenience, and deploy your code with a
clear dependency on it, since anyone can download it.  That is better than
releasing your package with a few ad hoc standard class modifications, and
hoping that they don't conflict with any code your users have written.

Long story short: it's useful that Ruby allows you to add methods to existing
classes, even built-ins like String and Array.  Some people rightfully are
uneasy about actually doing so in some situations, because of possible
conflicts.  This project offers a standard set of extensions in order to
mitigate that uneasiness by making them publicly available, and well
documented.

Thanks to the kind folk at InfoEther, Rich Kilmer and Tom Copeland, for
providing the means and encouragement to host projects like this at
http://www.rubyforge.org.


== Sample Code

  require 'extensions/all'
  require_relative 'data/samples'

  str = "Hello, \n\n  world!"
  str.define_method(:heading) {
    ('*** ' + self.join + ' ***').indent(3)
  }
  str.heading         # -> "   *** Hello, world! ***"

  person = OpenStruct.new do |p|
    p.name = 'John'
    p.age  = 90
  end

  class Person
    attr_reader :name, :age, :pension
    autoinit :name, :age do |p|
      @pension = 30000 + (@age - 65) * 350
    end
  end
  john = Person.new('John', 90)
  puts john.pension

  HELP = %{
    | Usage: ...
    | Lorem ipsum...
  }.trim('|')

  NUMBERS  = (1..100)
  squares  = NUMBERS.build_hash { |n| [n, n**2] }
  squares[4]                     # -> 16
  sq_roots = NUMBERS.build_hash { |n| [Math.sqrt(n), n] }
  _4_mod_7 = NUMBERS.partition_by { |n| n % 7 }[4]

  STR = "Hello, world!"
  STR.starts_with? "Hello"       # -> true
  STR.ends_with? "world"         # -> false
  File.write("hello.txt", STR)

  arr = [1, 3, 5]
  arr.rand                       # -> 1, 3, or 5
  arr.none? { |n| n.even? }      # -> true
  arr.one?  { |n| n > 4 }        # -> true

  Class.by_name "Process::Sys"   # -> Process::Sys
  Process::Sys.basename          # -> "Sys"


== Links

Home Page::     http://extensions.rubyforge.org (includes API documentation)
Project page::  http://www.rubyforge.org/projects/extensions
Wiki Page::     http://www.rubygarden.org/ruby?StandardClassExtensions


== Current Version and Status

Version 0.6 was released on 2004-12-08 and can be installed as a gem,
installed via the RPA, or downloaded from the project page.  Anybody is
welcome to access the CVS and see changes as they happen.  As always,
everything included is unit tested and well documented.

Several methods have been added since version 0.5.  <tt>ChangeLog</tt> has all
the details, and the changes are highlighted below.

Version 1.0 will (may?) occur when sufficient time has passed to make me
confident there are no bugs in this, and after a few more minor versions are
released with new methods.  Nobody has complained about bugs so far, and any
bugs would be easy to fix, so I have no problem using this package in my own
production code.

The long-term goal of <tt>extensions</tt> is to become part of the
<tt>addlib</tt> project.

The methods listed in this document will always reflect the most recent
released version, but the online RDoc will reflect what's in the latest CVS.


== Installation

The easiest way to install <tt>extensions</tt> is via RubyGems or the RPA.

  gem install -r extensions

  rpa update
  rpa install extensions

=== Tarball installation

The tarball version uses Minero Aoki's <tt>install.rb</tt>.  Run the
following, with the last one as root if appropriate.

  ruby install.rb config
  ruby install.rb setup
  ruby install.rb install

This will install the <tt>extensions/*</tt> files somewhere you can load them,
and +rbxtm+ in a +bin+ directory.  I've combined these commands into
<tt>install.sh</tt> if you want to run that instead.

=== Installing documentation

<tt>extensions</tt> offers you the opportunity to install its RDoc-generated
API documentation to your hard drive for ease of access.  Personally, I find
it easier to hit the website all the time, but...  It only works if you have
Rake installed.

From the base directory, run (as root if that applies to you):

  ruby install-doc.rb [location]

If you don't provide a location, it will default to
<tt>/usr/local/doc/ruby</tt>.  Well, that's on my platform; it will make an
intelligent guess on yours.  This is not a tried and tested documentation
installer; I wrote it just for this project, so please let me know if you're
not happy with it for any reason.

A side effect of installing the documentation is that it will be generated
into the <tt>build/rdoc</tt> directory of the package.

The "base directory" is the directory you unpacked from the tarball.  If you
installed via RubyGems, you might try this:

  gem unpack extensions
  cd extensions-0.5.0
  ruby install-doc.rb [location]
  cd ..
  rm -rf extensions-0.5.0

<tt>gem unpack</tt> is like having access to the tarball without having to
manually download it.


== What's included?

When you install this package, you can run the command +rbxtm+ ("Ruby
Extension Methods") to get a list of the methods implemented by this project.
At time of writing, this command gives (<tt>+</tt> indicates new method since
0.5).

 + Array#only
 + Array#rand
   Array#select!
   Binding#[]
   Binding#[]=
   Binding#defined?
   Binding#eval
   Binding#local_variables
   Binding.of_caller
   Class#autoinit
   Continuation.create
   Enumerable#build_hash
   Enumerable#collect_with_index
   Enumerable#collectf
   Enumerable#contains?
   Enumerable#has?
   Enumerable#includes?
   Enumerable#map_with_index
   Enumerable#mapf
 + Enumerable#none?
 + Enumerable#one?
   Enumerable#partition_by
   Hash#select!
   IO.write
   IO.writelines
   Integer#even?
   Integer#odd?
 + Kernel#require_relative
 + Module.by_name
 + Module#basename
 + Module#deep_const_get
   Numeric#format_s
   Object#define_method
   Object#in?
   Object#non_nil?
   Object#not_nil?
   Object#pp_s
   Object#singleton_class
   OpenStruct.new
   String#cmp
   String#ends_with?
   String#expand_tabs
   String#indent
   String#join
   String#leftmost_indent
   String#line
   String#outdent
   String#starts_with?
   String#taballto
   String#tabto
   String#trim
   Symbol#to_proc

The files that you can load are:

  extensions/all          (loads all the others)
  extensions/binding
  extensions/class
  extensions/continuation
  extensions/enumerable
  extensions/io
  extensions/kernel
  extensions/module
  extensions/numeric
  extensions/object
  extensions/ostruct
  extensions/string
  extensions/symbol

The RDoc documentation has all the details.  You can view this locally after
running <tt>ruby install-doc.rb</tt>, or you can view it online.  See the
links at the bottom of the page.


== Usage Information

Using this package is simple.  After installation, just include the following
line in your Ruby program:

  require 'extensions/all'

Then you can use any of the methods listed above.  If you want to only use
some of the methods, then load the file that names the class whose extensions
you wish to use.  For example:

  require 'extensions/string'

  puts report.indent(3)

If you install it via RubyGems, then you may need to do this in your code:

  require 'rubygems'
  require 'extensions/string'       # Or whatever you want to load.


== Technical Information

=== Special library files

This package has a simple framework to ensure safety and some correctness.
See the file <tt>_base.rb</tt> for more information.

There is a template used for new files: <tt>_template.rb</tt>.  It will raise an error
if you actually load it.

=== Unit testing

Unit tests are located in the <tt>test/</tt> directory, and are most easily
run using Rake with <tt>rake test</tt>.

=== How the package is organised

Relative to the root directory of the package:
bin/rbxtm::
    Lists the methods implemented by all the extensions that are installed.
    This file is installed in the +bin+ directory on the user's machine.
build/::
    A directory into which RDoc and packages are built.
etc/checklist::
    Contains a checklist for creating a new teeny version or a new minor
    release.
etc/website/index.html::
    <tt>index.html</tt> for the website.
etc/website/upload.sh::
    Copies <tt>index.html</tt> and the entire +rdoc+ directory to the website.
lib/extensions/*.rb::
    The extensions libraries themselves.

In the root directory:
ChangeLog::
    Records changes to the package (after v0.2).
HISTORY::
    Documents the main changes between minor versions (before v0.2).
README::
    Either the file you're reading, or the source file for the file you're
    reading.
README.1st::
    Instructions for generating documentation (specifically README.html)
Rakefile::
    Encapsulates all sorts of project tasks: generate documentation, create a
    tarball or gem for release, run unit tests, list the <tt>extensions</tt>
    methods.  This replaces three special-purpose scripts and does a better
    job to boot.  Thanks Jim!
VERSION::
    Current version of the package.  Used to decide on a directory for
    installing documentation.
install-doc.rb::
    Generates +rdoc+ documentation and installs it in a directory like
    <tt>/usr/local/doc/ruby/extensions-0.2.0/</tt>.
install.rb::
    Minero Aoki's installer.  Installs the package on your system.
install.sh::
    Front-end for <tt>install.rb</tt> so you don't have to run it three times.

== Feedback

If you would like to report a bug, suggest a method for inclusion, or make
some other suggestion (documentation, package layout, etc.), then head to the
project page (see links at end of document) and use the bug tracker or feature
request.  If neither of these is appropriate, or if you want to discuss
something before submitting, please contact me via email.


== Licence

Ruby/Extensions (http://extensions.rubyforge.org) is copyrighted free software
created and maintained by Gavin Sinclair (mailto:gsinclair@soyabean.com.au)
and released under the same license as Ruby.

Standard disclaimer:
  THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  PURPOSE.


------

<i>
$Id: README,v 1.14 2004/12/08 13:39:09 gsinclair Exp $
vim: et sw=2 ts=2 sts=2 ai
</i>
