
= Ruby Facets

  "ALL YOUR BASE ARE BELONG TO US"


== Introduction

Ruby Facets is a collection of general purpose, pure-Ruby extensions and additions
for the Ruby programming language. Facets is divided into two libraries, one for the
extensions and the other for the additions. called Facets/CORE and Facets/MORE, respectively.

Facets/CORE is a large collection of methods which extend the core capabilities of Ruby's
built-in classes and modules. This collection of extension methods are unique by virtue of
their atomicity. The methods are stored individually so that each can be required independently.
This gives developers fine-grain control over which  extra methods to bring into his or her code.
The collection currently contains over 400 methods spanning 28 classes and modules. It is an
_atomic_ library in that the methods are packaged individually so that each can be _required_
independently. This gives the programmer greater control to include only the extra methods he
or she actually needs.

Facets/MORE are a collection of classes, modules and light frameworks whcih consitutes an ever
growing and improving source of reusable components. Some very nice additions are provided,
from an amazing SI Units system to an elegant Annotations system. And of course there are all
the more typical goodies like Tuple, Functor and Multiton.


== License

The collection PER COLLECTION is licensed as follows:

  Ruby Facets
  Copyright (c) 2004-2006 Thomas Sawyer

  Distributed under the terms of the Ruby license.

The Ruby license is a dual license that also provides for use of the GPL.
Complete texts of both licenses accompany this document (see doc/COPYING).

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Acknowledgments and Copyrights for particular snippets of borrowed code
are given in their respective source. All licenses are either compatible
with the Ruby license (namely the GPL) or the original author has given
permission for inclusion of their code under such lincense.


== Mission

Facets holds to the notion that the more we can reasonably integrate into
a common foundation directed toward general needs, the better that foundation 
will be able to serve everyone. There are a number of advantages here:

    * Better Code-reuse
    * Collaborative Improvements
    * Greater Name Consistency
    * One-stop Shop and Installation


== Status

The current status is quite good. While some parts are still considered
beta, everything is relatively usable.


== Installation

The easiest way to install is via RubyGems. On the command line enter:

  > gem install facets

To manually install, unpack the .tar.bz2 package and use the included
setup.rb script. For example:

  > tar -xvzf facets,YYYY-MM-DD.tbz
  > cd facets,YYYY-MM-DD
  > sudo ruby setup.rb


== Usage

For detailed usage of any given method or module please refer to the
API RDocs. Most are well documented. Assistance in improving 
documentation though is always appreciated.

The general require statement for an atomic facet extension is as follows: 

  require 'facet/<class|module>/<method-name>'

For example:

  require 'facet/time/stamp'

Teh path is alwasy lower. The name may differ a bit from the actual
method being required. For instance, if the name ends in ?, !, or = the
character is simply removed. For method names that are non-alphanumeric
althogether, a name is chosen according to the chracters and
prefixed with 'op_' for "operator" (see chart below).

Most "atoms" contain but a single method, but excpetions occur when methods
are very tightly related. In these case "stubs" are used to have one required
method require the group.

The use of "facet/" namespace techinally uses a redirection file to file in 
facets/core. Redirection can be bypassed however:

  require 'facets/core/time/stamp'

But this usage is discouraged and should only be used if it is for some
reason neccessary or you are developing a library for Facets itself.

If you are using more then a few facets it is recommended that before
requiring any of them you first require the main facility.

  require 'facets'

This loads a set of facets considered "BASE" --currently a couple dozen
very basic methods, and adds the facets library directories to the end
of Ruby's load path. This allows you to require facets without even using
the 'facet/...' prefix. Eg.

  require 'string/blank'

A handful of extension sets are also available. For example,

  require 'facet/string_as_array'

adds some methods to Array that allow a String to behave more like
an array of characters. Other useful sets include, 'random' which
loads every facet method related to randomness and 'inflect' which
loads a number of methods for manipulating strings in high-level
ways, like #camelize and #pluralize.

It also should be pointed out that class methods are stored under
the 'self' directory of a class. For example, to load the
File::read_list method.

  require 'facet/file/self/read_list'

Using a Facets/MORE library of modules, classes or microframeworks
is essentially the same. You can use the redirection path. Eg.

  require 'facet/basicobject'

Or do so directly.

  require 'facets/more/basicobject'

Again, if you load the main facility, you can eliminate the need for the 'facet/' prefix.

  require 'facets'
  require 'basicobject'

Understand that on the off chance that another library has the same name as
one of Facets' everything will still work fine. You will just not be able to use the
prefixless shorcut to require it.

For details pertaining to the functionality of each feature, please see the API Docs.

== Important Considerations for certain Facets

Some caution should be taken when using certain facets.
What follows ois list of such facets and the reasons
these particular facets should given special consideration.

Some facets require other files to be loaded first
that are not loaded automatically, like fileutils
(i.e. they are part of the standard lib, not core).
The file include all of the following.

  date/*
  fileutils/*
  ostruct/*
  logger/*
  gem/*

Others effect the system in slightly non-standard ways.
Though such changes are kept to a minumim and intended
to be backward compatible, there still may be edge cases
that could cause another library to misbehave. 
The following is a list known facets that may have 
this potential.

  array/op_fetch.rb
  array/op_store.rb
  binding/self/of_caller.rb
  hash/op_fetch.rb
  hash/op_store.rb
  numeric/succ.rb
  numeric/pred.rb
  string/succ.rb
  string/unpack.rb
  module/attr.rb

There are also some facets that are potentially unsafe b/c
they change Ruby's default behavior in a nonconvential
manner and hence are not designed to be backward compatible.
Using these with a pre-existent program may cause the program
to misbehave. So while they can be useful, be sure to 
understand exactly what they do before putting them to 
 serious use.

  hash/each.rb
  module/methods.rb
  object/method.rb
  nilclass/op_fetch.rb
  nilclass/empty.rb
  nilclass/include.rb
  nilclass/size.rb
  nilclass/length.rb
  nilclass/method_missing.rb

== Facets' Directory Layout

There are two subdirectories in Facets library, 'core', which stores
the method extensions and 'more' which store the modules, classes and
micorframeworks.

The layout of Facets' core method files is straightfoward and well organized.
All individual methods are stored in subdirectories under their effected 
downcased class' or module's name.

  '<class|module>/<method-name>'

Class method are stored in the same manner but under a 'self' subdirectory.

  'core/<class|module>/self/<method-name>'

== Method File Names

Operators are stored in the file system using english names. For instance for
Proc#* is 'proc/op_mul'.

For reference, here is the chart.

     +@   => op_plus_self
     -@   => op_minus_self
     +    => op_plus
     -    => op_minus
     **   => op_pow
     *    => op_mul
     /    => op_div
     %    => op_mod
     ~    => op_tilde
     <=>  => op_cmp
     <<   => op_lshift
     >>   => op_rshift
     <    => op_lt
     >    => op_gt
     ===  => op_case_eq
     ==   => op_equal
     =~   => op_apply
     <=   => op_lt_eq
     >=   => op_gt_eq
     |    => op_or
     &    => op_and
     ^    => op_xor
     []=  => op_store
     []   => op_fetch

Facets simply takes the '*' and translates it into a string acceptable
to all file systems. Also, if a method ends in '=', '?' or '!' it is 
simply removed.


== Contribute

This project thrives on contribution.

If you have any extension methods, classes, modules or small frameworks
that you think have general applicability and would like to see them 
included in this project, don't hesitiate to submit. There's a very good
chance it will be included.  Also, if you have better versions of any thing
already included or simply have a patch, they too are more than welcome.
We want Ruby Facets to be of the highest quality.


== Authors

This collection was put together by, and largely written by Thomas Sawyer
(aka Trans). He can be reached via email at transfire at gmail.com.

Some parts of this collection were written and/or inspired by other
persons. Fortunately nearly all were copyrighted under the same open
license, the Ruby License. In the few excpetions I have included the
copyright notice with the source code. 

Any code file not specifically labelled shall fall under the Ruby License.

In all cases, I have made every effort to give credit where credit is due.
You will find these copyrights, thanks and acknowledgements embedded in the
source code, and an unobtrusive "Author(s)" section is given in the RDocs.

Also see the AUTHORS file for a list of all contributing Rubyists.

If anyone is missing from the list, please let me know and 
I will correct right away. Thanks.


== Pitch

  ALL YOUR BASE ARE BELONG TO RUBY!


----

[1] A lot of mental anguish went into finding this good project name Ruby Facets.
    Of course, in the end only one name can take the honor. Other good names
    which were considered: Calibre, Florida and California, Warchest w/ Atomix,
    Downs & Ace, Trix & Atomx and even Pillbox & Pills (a _why suggestion).
    Then the names that almost won out and were used for a good while:
    Nano Methods and Mega Modules --great names but a little to "fad".
    Finally let's not forget even older "working" titles that were used
    along the way: Raspberry, ABC, Succ and the very original Tomslib.

# Copyright (c)2006 Thomas Sawyer
# facets.rubyforge.com
# (ruby-lang.org) Do you Ruby?
