This is Info file pm.info, produced by Makeinfo version 1.68 from the
input file bigpm.texi.


File: pm.info,  Node: Business/OnlinePayment,  Next: Business/OnlinePayment/AuthorizeNet,  Prev: Business/ISSN,  Up: Module List

Perl extension for online payment processing
********************************************

NAME
====

   Business::OnlinePayment - Perl extension for online payment processing

SYNOPSIS
========

     use Business::OnlinePayment;

     my $transaction = new Business::OnlinePayment($processor, %processor_info);
     $transaction->content(
                           type       => 'Visa',
                           amount     => '49.95',
                           cardnumber => '1234123412341238',
                           expiration => '0100',
                           name       => 'John Q Doe',
                          );
     $transaction->submit();

     if($transaction->is_success()) {
       print "Card processed successfully: ".$transaction->authorization()."\n";
     } else {
       print "Card was rejected: ".$transaction->error_message()."\n";
     }

DESCRIPTION
===========

   Business::OnlinePayment is a generic module for processing payments
through online credit card processors, electronic cash systems, etc.

METHODS AND FUNCTIONS
=====================

new($processor, %processor_options);
------------------------------------

   Create a new Business::OnlinePayment object, $processor is required,
and defines the online processor to use.  If necessary, processor options
can be specified, currently supported options are 'Server', 'Port', and
'Path', which specify how to find the online processor
(https://server:port/path), but individual processor modules should supply
reasonable defaults for this information, override the defaults only if
absolutely necessary (especially path), as the processor module was
probably written with a specific target script in mind.

content(%content);
------------------

   The information necessary for the transaction, this tends to vary a
little depending on the processor, so we have chosen to use a system which
defines specific fields in the frontend which get mapped to the correct
fields in the backend.  The currently defined fields are:

   * type

     Transaction type, supported types are: Visa, MasterCard, American
     Express, Discover, Check (not all processors support all these
     transaction types).

   * login

     Your login name to use for authentication to the online processor.

   * password

     Your password to use for authentication to the online processor.

   * action

     What to do with the transaction (currently available are: Normal
     Authorization, Authorization Only, Credit, Post Authorization)

   * description

     A description of the transaction (used by some processors to send
     information to the client, normally not a required field).

   * amount

     The amount of the transaction, most processors dont want dollar signs
     and the like, just a floating point number.

   * invoice_number

     An invoice number, for your use and not normally required, many
     processors require this field to be a numeric only field.

   * customer_id

     A customer identifier, again not normally required.

   * name

     The customers name, your processor may not require this.

   * address

     The customers address (your processor may not require this unless you
     are requiring AVS Verification).

   * city

     The customers city (your processor may not require this unless you
     are requiring AVS Verification).

   * state

     The customers state (your processor may not require this unless you
     are requiring AVS Verification).

   * zip

     The customers zip code (your processor may not require this unless
     you are requiring AVS Verification).

   * country

     Customer's country.

   * phone

     Customer's phone number.

   * fax

     Customer's fax number.

   * email

     Customer's email address.

   * card_number

     Credit card number (obviously not required for non-credit card
     transactions).

   * exp_date

     Credit card expiration (obviously not required for non-credit card
     transactions).

   * account_number

     Bank account number for electronic checks or electronic funds
     transfer.

   * routing_code

     Bank's routing code for electronic checks or electronic funds
     transfer.

   * bank_name

     Bank's name for electronic checks or electronic funds transfer.

submit();
---------

   Submit the transaction to the processor for completion

is_success();
-------------

   Returns true if the transaction was submitted successfully, false if it
failed (or undef if it has not been submitted yet).

result_code();
--------------

   Returns the precise result code that the processor returned, these are
normally one letter codes that don't mean much unless you understand the
protocol they speak, you probably don't need this, but it's there just in
case.

test_transaction();
-------------------

   Most processors provide a test mode, where submitted transactions will
not actually be charged or added to your batch, calling this function with
a true argument will turn that mode on if the processor supports it, or
generate a fatal error if the processor does not support a test mode
(which is probably better than accidentally making real charges).

require_avs();
--------------

   Providing a true argument to this module will turn on address
verification (if the processor supports it).

transaction_type();
-------------------

   Retrieve the transaction type (the 'type' argument to contents();).
Generally only used internally, but provided in case it is useful.

error_message();
----------------

   If the transaction has been submitted but was not accepted, this
function will return the provided error message (if any) that the
processor returned.

authorization();
----------------

   If the transaction has been submitted and accepted, this function will
provide you with the authorization code that the processor returned.

server();
---------

   Retrieve or change the processor submission server address (CHANGE AT
YOUR OWN RISK).

port();
-------

   Retrieve or change the processor submission port (CHANGE AT YOUR OWN
RISK).

path();
-------

   Retrieve or change the processor submission path (CHANGE AT YOUR OWN
RISK).

AUTHOR
======

   Jason S Kohles, jason@mediabang.com

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.

SEE ALSO
========

   For verification of credit card checksums, see `Business::CreditCard'
in this node.


File: pm.info,  Node: Business/OnlinePayment/AuthorizeNet,  Next: Business/OnlinePayment/Cardstream,  Prev: Business/OnlinePayment,  Up: Module List

AuthorizeNet backend for Business::OnlinePayment
************************************************

NAME
====

   Business::OnlinePayment::AuthorizeNet - AuthorizeNet backend for
Business::OnlinePayment

SYNOPSIS
========

     use Business::OnlinePayment;

     my $tx = new Business::OnlinePayment("AuthorizeNet");
     $tx->content(
         type           => 'VISA',
         login          => 'testdrive',
         password       => '',
         action         => 'Normal Authorization',
         description    => 'Business::OnlinePayment test',
         amount         => '49.95',
         invoice_number => '100100',
         customer_id    => 'jsk',
         name           => 'Jason Kohles',
         address        => '123 Anystreet',
         city           => 'Anywhere',
         state          => 'UT',
         zip            => '84058',
         card_number    => '4007000000027',
         expiration     => '09/99',
     );
     $tx->submit();

     if($tx->is_success()) {
         print "Card processed successfully: ".$tx->authorization."\n";
     } else {
         print "Card was rejected: ".$tx->error_message."\n";
     }

SUPPORTED TRANSACTION TYPES
===========================

Visa, MasterCard, American Express, Discover
--------------------------------------------

   Content required: type, login, password, action, amount, name,
card_number, expiration.

Check
-----

   Content required: type, login, password, action, amount, name,
account_number, routing_code, bank_name.

DESCRIPTION
===========

   For detailed information see *Note Business/OnlinePayment:
Business/OnlinePayment,.

AUTHOR
======

   Jason Kohles, jason@mediabang.com

SEE ALSO
========

   perl(1). *Note Business/OnlinePayment: Business/OnlinePayment,.


File: pm.info,  Node: Business/OnlinePayment/Cardstream,  Next: Business/UPC,  Prev: Business/OnlinePayment/AuthorizeNet,  Up: Module List

Cardstream Plugin for Business::OnlinePayment
*********************************************

NAME
====

   Business::OnlinePayment::Cardstream - Cardstream Plugin for
Business::OnlinePayment

SYNOPSIS
========

     use Business::OnlinePayment;
     my $Cardstream = new Business::OnlinePayment("Cardstream");
     
     $Cardstream->content(
     	type		=>	'visa',
     	login		=>	'mylogin',
     	passwd		=>	'mypassword',
     	action		=>	'authorise',
     	amount		=>	'5.00',
     	name		=>	'John Watson',
     	address		=>	'6 Elms, Oak Road.',
     	card_number	=>	'4725444499992827',
     	expiration	=>	'0112' #YYMM
     	);
     $Cardstream->submit;
     
     if ($Cardstream->is_success) {
     	print "Success, Auth Code is ".$Cardstream->authorization;
     } else {
     	print "Failed, Error message ".$Cardstream->error_message;
     }

     my @RESPONSE = split('\|',$Cardstream->server_response);
     my %response_hash = @RESPONSE;

Supported Cards
===============

Visa, MasterCard, Switch	(Check website for updates)
----------------------------------------------------

   Switch cards require issue number; $Cardstream->content(issue => '1')

NOTES
=====

Merchant accounts
-----------------

   A Cardstream merchant account is free of charge to set-up.  Cardstream
operates on a commission basis. Please see http://www.cardstream.com for
pricing information, or contact sales@cardstream.com.

Expiration dates
----------------

   Cardstream.pm requires expiration dates in APACS/30 Standard format,
which, unlike what is printed on the card, is YYMM.

server-response
---------------

   The auth code and error messages are stored into
$Cardstream->authorization and $Cardstream->error_message, however should
you require more debugging information, server-response contains a pipe
delimited hash consisting of the error code, text message from bank...etc.

DESCRIPTION
===========

   For detailed information see *Note Business/OnlinePayment:
Business/OnlinePayment,.

AUTHOR
======

   Craig R. Belcham, crb@cardstream.com.

SEE ALSO
========

   perl(1). *Note Business/OnlinePayment: Business/OnlinePayment,.
http://www.cardstream.com for merchant account information.  =cut


File: pm.info,  Node: Business/UPC,  Next: Business/UPS,  Prev: Business/OnlinePayment/Cardstream,  Up: Module List

Perl extension for manipulating Universal Product Codes
*******************************************************

NAME
====

   Business::UPC - Perl extension for manipulating Universal Product Codes

SYNOPSIS
========

     use Business::UPC;

     # Constructors:
     # create a UPC object using standard (type-A) UPC
     $upc = new Business::UPC('012345678905');
     # create a UPC object using zero-supressed (type-E) UPC
     $upc = type_e Business::UPC('01201303');

     # is the UPC valid (correct check digit)?
     $upc->is_valid;

     # correct the check digit
     $upc->fix_check_digit;

     # get the numeric string:
     $upc->as_upc;	# same as $upc->as_upc_a;
     $upc->as_upc_a;
     $upc->as_upc_e;

     # get the components;
     $upc->number_system;		# UPC number system character
     $upc->mfr_id;		# Manufacturer ID
     $upc->prod_id;		# Product ID
     $upc->check_digit;		# Check Digit

     # more information about the components:
     $upc->number_system_description	# explain number_system

     # methods specific to coupon UPC codes:
     $upc->is_coupon;
     $upc->coupon_family_code;		# 3-digit family code
     $upc->coupon_family_description;	# explain above
     $upc->coupon_value_code;		# 2-digit value code
     $upc->coupon_value;			# explain above

DESCRIPTION
===========

   More detail to come later...

AUTHOR
======

   Rob Fugina, robf@geeks.com

SEE ALSO
========

   perl(1).


File: pm.info,  Node: Business/UPS,  Next: Business/US_Amort,  Prev: Business/UPC,  Up: Module List

A UPS Interface Module
**********************

NAME
====

   Business::UPS - A UPS Interface Module

SYNOPSIS
========

     use Business::UPS;

     my ($shipping,$ups_zone,$error) = getUPS(qw/GNDCOM 23606 23607 50/);
     $error and die "ERROR: $error\n";
     print "Shipping is \$$shipping\n";
     print "UPS Zone is $ups_zone\n";

     %track = UPStrack("z10192ixj29j39");
     $track{error} and die "ERROR: $track{error};

     # 'Delivered' or 'In-transit'
     print "This package is $track{Current Status}\n";

DESCRIPTION
===========

   A way of sending four arguments to a module to get shipping charges
that can be used in, say, a CGI.

REQUIREMENTS
============

   I've tried to keep this package to a minimum, so you'll need:

   * Perl 5.003 or higher

   * LWP Module

ARGUMENTS for getUPS()
======================

   Call the subroutine with the following values:

     1. Product code (see product-codes.txt)
     2. Origin Zip Code
     3. Destination Zip Code
     4. Weight of Package

   and optionally:

     5.  Country Code, (see country-codes.txt)
     6.  Rate Chart (drop-off, pick-up, etc - see below)
     6.  Length,
     7.  Width,
     8.  Height,
     9.  Oversized (defined if oversized), and
     10. COD (defined if C.O.D.)

  1. Product Codes:

          1DM		Next Day Air Early AM
          1DML		Next Day Air Early AM Letter
          1DA		Next Day Air
          1DAL		Next Day Air Letter
          1DP		Next Day Air Saver
          1DPL		Next Day Air Saver Letter
          2DM		2nd Day Air A.M.
          2DA		2nd Day Air
          2DML		2nd Day Air A.M. Letter
          2DAL		2nd Day Air Letter
          3DS		3 Day Select
          GNDCOM	Ground Commercial
          GNDRES	Ground Residential
          XPR		Worldwide Express
          XDM		Worldwide Express Plus
          XPRL		Worldwide Express Letter
          XDML		Worldwide Express Plus Letter
          XPD		Worldwide Expedited

     In an HTML "option" input it might look like this:

          <OPTION VALUE="1DM">Next Day Air Early AM
          <OPTION VALUE="1DML">Next Day Air Early AM Letter
          <OPTION SELECTED VALUE="1DA">Next Day Air
          <OPTION VALUE="1DAL">Next Day Air Letter
          <OPTION VALUE="1DP">Next Day Air Saver
          <OPTION VALUE="1DPL">Next Day Air Saver Letter
          <OPTION VALUE="2DM">2nd Day Air A.M.
          <OPTION VALUE="2DA">2nd Day Air
          <OPTION VALUE="2DML">2nd Day Air A.M. Letter
          <OPTION VALUE="2DAL">2nd Day Air Letter
          <OPTION VALUE="3DS">3 Day Select
          <OPTION VALUE="GNDCOM">Ground Commercial
          <OPTION VALUE="GNDRES">Ground Residential

  2. Origin Zip(tm) Code

     Origin Zip Code as a number or string (NOT +4 Format)

  3. Destination Zip(tm) Code

     Destination Zip Code as a number or string (NOT +4 Format)

  4. Weight

     Weight of the package in pounds

  5. Country

     Defaults to US

  6. Rate Chart

     How does the package get to UPS:

     Can be one of the following:

          Regular Daily Pickup
          On Call Air
          One Time Pickup
          Letter Center
          Customer Counter


ARGUMENTS for UPStrack()
========================

   The tracking number.

     use Business::UPS;
     %t = UPStrack("1ZX29W290250xxxxxx");
     print "This package is $track{Current Status}\n";

RETURN VALUES
=============

getUPS()
          The raw http get() returns a list with the following values:

          ##  Desc		Typical Value
          --  ---------------   -------------
          0.  Name of server: 	UPSOnLine3
          1.  Product code:	GNDCOM
          2.  Orig Postal:	23606
          3.  Country:		US
          4.  Dest Postal:	23607
          5.  Country:		US
          6.  Shipping Zone:	002
          7.  Weight (lbs):	50
          8.  Sub-total Cost:	7.75
          9.  Addt'l Chrgs:	0.00
          10. Total Cost:	7.75
          11. ???:		-1

          If anyone wants these available for some reason, let me know.

UPStrack() 	 The hash that's returned is like the following:
          'Delivered on' 	=> '1-22-1998 at 2:58 PM'
          'Notice' 		=> 'UPS authorizes you to use UPS...'
          'Received by'		=> 'DR PORCH'
          'Addressed to'	=> 'NEWPORT NEWS, VA US'
          'scan'		=>  HASH(0x146e0c) (more later...)
          'Current Status'	=> 'Delivered'
          'Delivered to'	=> 'RESIDENTIAL'
          'Sent on'		=> '1-20-1998'
          'UPS Service'		=> '2ND DAY AIR'
          'Tracking Number' 	=> '1ZX29W29025xxxxxx'
          'Scanning'		=> (See next paragraph)

     Notice the key 'Scanning' is a newline (\n) delineated list of
     scanning locations.  Each line has two parts: 1. Time/Date of scan
     and 2. Type of scan.  In its scalar context, it looks like this:

          1-22-19982:58 PM NEWPORT NEWS-OYSTER, VA US = DELIVERED
          1-21-199811:37 PM RICHMOND, VA US = LOCATION SCAN
          2:05 PM PHILA AIR HUB, PA US = LOCATION SCAN
          1-20-199811:35 PM PHILA AIR HUB, PA US = LOCATION SCAN

     ...but a line or two of code can make it very usable like this:

          foreach $line (split "\n", $track{Scanning}) {
            my ($location, $type) = split /=/, $line;
            print "At $location, the shipment was $type\n";
          }

EXAMPLE
=======

getUPS()
     To retreive the shipping of a 'Ground Commercial' Package weighing
     25lbs. sent from 23001 to 24002 this package would be called like
     this:

          #!/usr/local/bin/perl
          use Business::UPS;

          my ($shipping,$ups_zone,$error) = getUPS(qw/GNDCOM 23001 23002 25/);
          $error and die "ERROR: $error\n";
          print "Shipping is \$$shipping\n";
          print "UPS Zone is $ups_zone\n";

UPStrack()
          #!/usr/local/bin/perl

          use Business:UPS;

          %t = UPStrack("z10192ixj29j39");
          $t{error} and die "ERROR: $t{error};
          
          print "This package is $t{'Current Status'}\n"; # 'Delivered' or
          						  # 'In-transit'
          print "More info:\n";
          foreach $key (keys %t) {
            print "KEY: $key = $t{$key}\n";
          }

BUGS
====

   Let me know.

AUTHOR
======

   Mark Solomon <msolomon@seva.net>

   mailto:msolomon@seva.net

   http://www.seva.net/~msolomon/

   NOTE: UPS is a registered trademark of United Parcel Service.

SEE ALSO
========

   perl(1).


File: pm.info,  Node: Business/US_Amort,  Next: ByteCache,  Prev: Business/UPS,  Up: Module List

class encapsulating US-style amortization
*****************************************

NAME
====

   Business::US_Amort - class encapsulating US-style amortization

SYNOPSIS
========

     use Business::US_Amort;
     my $loan = Business::US_Amort->new;
     $loan->principal(123654);
     $loan->interest_rate(9.25);
     $loan->term(20);
     
     my $add_before_50_amt = 700;
     sub add_before_50 {
       my $this = $_[0];
       if($this->{'_month_count'} == 50) {
         $this->{'_monthly_payment'} += $add_before_50_amt;
       }
     }
     $loan->callback_before_monthly_calc(\&add_before_50);
     $loan->start_date_be_now;
     
     $loan->run;
     $loan->dump_table;
     
     print "Total paid toward interest: ", $loan->total_paid_interest, "\n";

DESCRIPTION
===========

   This class encapsulates amortization calculations figured according to
what I've been led to believe is the usual algorithm for loans in the USA.

   I used to think amortization was simple, just the output of an algorithm
that'd take just principle, term, and interest rate, and return the
monthly payment and maybe something like total paid toward interest.
However, I discovered that there's a need for loan calculations where,
say, between the 49th and 50th month, your interest rate drops, or where
you decide to add $100 to your monthly payment in the 32nd month.

   So I wrote this class, so that I could amortize simply in simple cases
while still allowing any kind of strangeness in complex cases.

FUNCTIONS
=========

   This module provides one function, which is a simple amortizer.  This
is just to save you the bother of method calls when you really don't need
any frills.

Business::US_Amort::simple $principal, $interest_rate, $term
     Amortizes based on these parameters.  In a scalar context, returns
     the initial monthly payment.

     In an array context, returns a three item list consisting of: the
     initial monthly payment, the total paid toward interest, and the loan
     object, in case you want to do things with it.

   Example usages:

     $monthly_payment = Business::US_Amort::simple(123654, 9.25, 20);
     
     ($monthly_payment, $total_toward_interest, $o)
       = Business::US_Amort::simple(123654, 9.25, 20);

   Of course, if you find yourself doing much of anything with the loan
object, you probably should be using the OOP interface instead of the
functional one.

OBJECT ATTRIBUTES
=================

   All attributes for this class are scalar attributes.  They can be read
via:

     $thing = $loan->principal     OR    $thing = $loan->{'principal'}

   or set via:

     $loan->principal(VALUE)       OR    $loan->{'principal'} = VALUE

MAIN ATTRIBUTES
---------------

   These attributes are used as parameters to the run method.

principal
     The principal amount of the loan.

interest_rate
     The annual rate, expressed like 8.3, not like .083.

     Note that if you're defining callbacks, you can change this attribute
     at any time in your callbacks, to change the rate of interest from
     then on.

term
     The term of the loan, in years, not months.

callback_before_monthly_calc
     If set, this should be a coderef to a routine to call at the
     *beginning* of each month, *before any* calculations are done.  The
     one parameter passed to this routine, in $_[0], is the object.  See
     the SYNOPSIS, above, for an example.

callback_after_monthly_calc
     If set, this should be a coderef to a routine to call at the end of
     each month, *after all* monthly calculations are done.  The one
     parameter passed to this routine, in $_[0], is the object.

block_table
     If set to true, this inhibits run from adding to table.  (This is
     false by default.) If you're not going to access table, set this to
     true before calling run - it'll speed things up and use less memory.

start_date
     If set to a date in the format "YYYY-MM", _date will be defined
     appropriately for each month.  You can set start_date to the current
     month by just saying $loan->start_date_be_now.

cent_rounding
     If set to true, figures are rounded to the nearest cent at appropriate
     moments, so as to avoid having to suppose that the debtor is to make a
     monthly payment of $1025.229348723948 on a remaining principal of
     $196239.12082309123408, or the like.

   These attributes are set by the run method:

initial_monthly_payment
     The monthly payment that follows from the basic amortization
     parameters given.  Compare with _monthly_payment.

total_paid_interest
     The total amount paid toward interest during the term of this loan.

total_month_count
     The total number of months the loan took to pay off.  E.g., "12" for
     a loan that took 12 months to pay off.

table
     This will be a reference to a list of copies made of the object
     ("snapshots") each month.  You can then use this if you want to
     generate a dump of particular values of the object's state in each
     month.

     Note that snapshots have their am_snapshot attribute set to true, and
     have their table attribute set to undef.  (Otherwise this'd be a
     circular data structure, which would be a hassle for you and me.)

error
     A string explaining any error that might have occurred, which
     would/should accompany run returning 0.  Use like:

          $loan->run or die("Run failed: " . $loan->error);

   Other attributes:

am_snapshot
     This attribute is set to true in snapshots, as stored in table.

_month_count_limit
     This is a variable such that if the month count ever exceeds this
     amount, the main loop will abort.  This is intended to keep the
     iterator from entering any infinite loops, even in pathological cases.
     Currently the run method sets this to twelve plus twice the number of
     months that it's expected this loan will take.  Increase as necessary.

INTERATION ATTRIBUTES
---------------------

   These are attributes of little or no interest once run is done, but may
be of interest to callbacks while run is running, or may be of interest in
examining snapshots in table.

_month_count
     This is how many months we are into the loan.  The first month is 1.

_abort
     If you want callbacks to be able to halt the iteration for some
     reason, you can have them set _abort to true.  You may also choose to
     set error to something helpful.

_monthly_payment
     The amount to be paid to toward the principal each month. At the start
     of the loan, this is set to whatever initial_monthly_payment is
     figured to be, but you can manipulate _monthly_payment with callbacks
     to change how much actually gets paid when.

_remainder
     The balance on the loan.

_date
     The given month's date, if known, in the format "YYYY-MM".  Unless
     you'd set the start_date to something, this will be undef.

_h
     The interest to be paid this month.

_old_amount
     What the remainder was before we made this month's payment.

_c
     The current monthly payment, minus the monthly interest, possibly
     tweaked in the last month to avoid paying off more than is actually
     left on the loan.

METHODS
=======

$loan = Business::US_Amort->new
     Creates a new loan object.

$loan->copy
     Copies a loan object or snapshot object.  Also performs a somewhat
     deep copy of its table, if applicable.

$loan->destroy
     Destroys a loan object.  Probably never necessary, given Perl's
     garbage collection techniques.

$loan->start_date_be_now
     This sets start_date to the current date, based on $^T.

$loan->run
     This performs the actual amortization calculations.  Returns 1 on
     success; otherwise returns 0, in which case you should check the
     error attribute.

$loan->dump_table
     This method dumps a few fields selected from snapshots in the table
     of the given object.  It's here more as example code than as anything
     particularly useful.  See the source.  You should be able to use this
     as a basis for making code of your own that dumps relevant fields from
     the contents of snapshots of loan objects.

REMEMBER
========

   When in panic or in doubt, run in circles, scream and shout.

   Or read the source.  I really suggest the latter, actually.

WARNINGS
========

   * There's little or no sanity checking in this class.  If you want to
amortize a loan for $2 at 1% interest over ten million years, this class
won't stop you.

   * Perl is liable to produce tiny math errors, like just about any other
language that does its math in binary but has to convert to and from
decimal for purposes of human interaction.  I've seen this surface as tiny
discrepencies in loan calculations - "tiny" as in less than $1 for even
multi-million-dollar loans amortized over decades.

   * Moreover, oddities may creep in because of round-off errors. This
seems to result from the fact that the formula that takes term, interest
rate, and principal, and returns the monthly payment, doesn't know that a
real-world monthly payment of "$1020.309" is impossible - and so that
ninth of a cent difference can add up across the months.  At worst, this
may cause a 30-year-loan loan coming to term in 30 years and 1 month, with
the last payment being needed to pay off a balance of two dollars, or the
like.

   These errors have never been a problem for any purpose I've put this
class to, but be on the look out.

DISCLAIMER
==========

   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*.

   But let me know if it gives you any problems, OK?

COPYRIGHT
=========

   Copyright 1999, 2000, Sean M. Burke `sburke@cpan.org', all rights
reserved.  This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

AUTHOR
======

   Sean M. Burke `sburke@cpan.org'


File: pm.info,  Node: ByteCache,  Next: ByteLoader,  Prev: Business/US_Amort,  Up: Module List

byte-compile modules when needed
********************************

NAME
====

   ByteCache - byte-compile modules when needed

SYNOPSIS
========

     use ByteCache;
     use Other::Module;

DESCRIPTION
===========

   This module causes any modules loaded after it to be loaded in bytecode
compiled format. If a bytecode compiled version of the module does not
currently exist, ByteCache will call the compiler to create one and then
save it away.

WARNING
=======

   This module is dependent on the compiler suite, and is therefore
B&lt;very&gt; experimental. Your results may very. Do not use in
production systems.

AUTHOR
======

   Simon Cozens, `simon@brecon.co.uk'

SEE ALSO
========

   *Note Perl: (perl.info)perl,, `perlcc' in this node, *Note ByteLoader:
ByteLoader,


File: pm.info,  Node: ByteLoader,  Next: C/DynaLib,  Prev: ByteCache,  Up: Module List

load byte compiled perl code
****************************

NAME
====

   ByteLoader - load byte compiled perl code

SYNOPSIS
========

     use ByteLoader 0.03;
     <byte code>

     use ByteLoader 0.03;
     <byte code>

DESCRIPTION
===========

   This module is used to load byte compiled perl code. It uses the source
filter mechanism to read the byte code and insert it into the compiled
code at the appropriate point.

AUTHOR
======

   Tom Hughes <tom@compton.nu> based on the ideas of Tim Bunce and others.

SEE ALSO
========

   perl(1).


File: pm.info,  Node: C/DynaLib,  Next: C/DynaLib/Struct,  Prev: ByteLoader,  Up: Module List

Perl interface to C compiled code.
**********************************

NAME
====

   C::DynaLib - Perl interface to C compiled code.

SYNOPSIS
========

     use C::DynaLib;
     use sigtrap;	# recommended

     $lib = new C::DynaLib( $linker_arg );

     $func = $lib->DeclareSub( $symbol_name
     			    [, $return_type [, @arg_types] ] );
     # or
     $func = $lib->DeclareSub( { "name"    => $symbol_name,
     			      [param => $value,] ... } );
     # or
     use C::DynaLib qw(DeclareSub);
     $func = DeclareSub( $function_pointer,
     		      [, $return_type [, @arg_types] ] );
     # or
     $func = DeclareSub( { "ptr" => $function_pointer,
     			[param => $value,] ... } );

     $result = $func->( @args );

     $callback = new C::DynaLib::Callback( \&my_sub,
     			$return_type, @arg_types );
     $callback_pointer = $callback->Ptr();

PLUG FOR PERL XS
================

   If you have a C compiler that Perl supports, you will get better
results by writing XSubs than by using this module.  *I GUARANTEE IT!*  It
may take you longer to do what you want, but your code will be much more
solid and portable.  See *Note Perlxs: (perl.info)perlxs,.

   This module brings "pointers" to Perl.  Perl's non-use of pointers is
one of its great strengths.  If you don't know what I mean, then maybe you
ought to practice up a bit on C or C++ before using this module.  If
anything, pointers are more dangerous in Perl than in C, due to Perl's
dynamic, interpretive nature.

   The XSub interface and Perl objects provide a means of calling C and
C++ code while preserving Perl's abstraction from pointers.  Once again, I
*urge* you to check out *Note Perlxs: (perl.info)perlxs,!  It's really
cool!!!

DESCRIPTION
===========

   This module allows Perl programs to call C functions in dynamic
libraries.  It is useful for testing library functions, writing simple
programs without the bother of XS, and generating C function pointers that
call Perl code.

   Your Perl must be of the dynamic variety and have a working DynaLoader
to use the dynamic loading capabilities of this module.  Be sure you
answered "y" when Configure (from the Perl source kit) asked, "Do you wish
to use dynamic loading?".

   The mechanics of passing arguments to and returning values from C
functions vary greatly among machines, operating systems, and compilers.
Therefore, Makefile.PL checks the Perl configuration and may even compile
and run a test program before the module is built.

   This module is divided into two packages, `C::DynaLib' and
`C::DynaLib::Callback'.  Each makes use of Perl objects (see *Note
Perlobj: (perl.info)perlobj,) and provides its own constructor.

   A `C::DynaLib' object corresponds to a dynamic library whose functions
are available to Perl.  A `C::DynaLib::Callback' object corresponds to a
Perl sub which may be accessed from C.

`C::DynaLib' public constructor
-------------------------------

   The argument to new may be the file name of a dynamic library.
Alternatively, a linker command-line argument (e.g., `"-lc"') may be
specified.  See `DynaLoader(3)' in this node for details on how such
arguments are mapped to file names.

   On failure, new returns undef.  Error information *might* be obtainable
by calling `DynaLoader::dl_error()'.

Declaring a library routine
---------------------------

   Before you can call a function in a dynamic library, you must specify
its name, the return type, and the number and types of arguments it
expects.  This is handled by `DeclareSub'.

   `C::DynaLib::DeclareSub' can be used as either an object method or an
ordinary sub.  You can pass its arguments either in a list (what we call
*positional parameters*) or in a hash (*named parameters*).

   The simplest way to use `DeclareSub' is as a method with positional
parameters.  This form is illustrated in the first example above and both
examples below.  When used in this way, the first argument is a library
function name, the second is the function return type, and the rest are
function argument types.

   *THIS IS VERY IMPORTANT*.  You must not forget to specify the return
type as the second argument to `DeclareSub'.  If the function returns
void, you should use "" as the second argument.

   C data types are specified using the codes used by Perl's pack and
unpack operators.  See `perlfunc(1)' in this node for their description.
As a convenience (and to hide system dependencies), `PTR_TYPE' is defined
as a code suitable for pointer types (typically `"i"').

   The possible arguments to `DeclareSub' are shown below.  Each is listed
under the name that is used when passing the arguments in a hash.

name
     The name of a function exported by `$lib'.  This argument is ignored
     in the non-method forms of `DeclareSub'.

`ptr'
     The address of the C function.  This argument is required in the
     non-method forms of `DeclareSub'.  Either it or the name must be
     specified in the method forms.

return
     The return type of the function, encoded for use with the pack
     operator.  Not all of the pack codes are supported, but the
     unsupported ones mostly don't make sense as C return types.  Functions
     that return a `struct' are not supported.  However, a pointer to
     struct is okay.

     Many C functions return pointers to various things.  If you have a
     function that returns `char *' and all you're interested in is the
     string (i.e., the `char' sequence pointed to, up to the first nul),
     then you may use `"p"' as the return type.  The `"P"' code (followed
     by a number of bytes) is also permissible.

     For the case where a returned pointer value must be remembered (for
     example, *malloc()*), use `PTR_TYPE'.  The returned scalar will be
     the pointer itself.  You can use unpack to find the thing pointed to.

args
     A list of the types of arguments expected by the function, specified
     using the notation of Perl's pack operator.  For example, `"i"' means
     an integer, `"d"' means a double, and `"p"' means a nul-terminated
     string pointer.  If you need to handle pointers to things other than
     Perl scalars, use type `PTR_TYPE'.

     Note: you probably don't want to use `"c"' or `"s"' here, since C
     normally converts the corresponding types (`char' and short) to int
     when passing them to a function.  The C::DynaLib package may or may
     not perform such conversions.  Use `"i"' instead.  Likewise, use
     `"I"' in place of `"C"' or `"S"', and `"d"' in place of `"f"'.  Stick
     with `"i"', `"I"', `"d"', `"p"', `"P"', and `PTR_TYPE' if you want to
     be safe.

     Passing structs by value is not generally supported, but you might
     find a way to do it with a given compiler by experimenting.

`decl'
     Allows you to specify a function's calling convention.  This is
     possible only with a named-parameter form of `DeclareSub'.  See below
     for information about the supported calling conventions.

`libref'
     A library reference obtained from either `DynaLoader::dl_load_file'
     or the `C::DynaLib::LibRef' method.  You must use a named-parameter
     form of `DeclareSub' in order to specify this argument.

Calling a declared function
---------------------------

   The returned value of `DeclareSub' is a code reference.  Calling
through it results in a call to the C function.  See `perlref(1)' in this
node on how to use code references.

Using callback routines
-----------------------

   Some C functions expect a pointer to another C function as an argument.
The library code that receives the pointer may use it to call an
application function at a later time.  Such functions are called
*callbacks*.

   This module allows you to use a Perl sub as a C callback, subject to
certain restrictions.  There is a hard-coded maximum number of callbacks
that can be active at any given time.  The default (4) may be changed by
specifying `CALLBACKS=number' on the Makefile.PL command line.

   A callback's argument and return types are specified using pack codes,
as described above for library functions.  Currently, the return value
must be interpretable as type int or void, so the only valid codes are
`"i"', `"I"', and "".  There are also restrictions on the permissible
argument types, especially for the first argument position.  These
limitations are considered bugs to be fixed someday.

   To enable a Perl sub to be used as a callback, you must construct an
object of class `C::DynaLib::Callback'.  The syntax is

     $cb_ref = new C::DynaLib::Callback( \&some_sub,
                       $ret_type, @arg_types );

   where `$ret_type' and `@arg_types' are the pack-style types of the
function return value and arguments, respectively.  `\&some_sub' must be a
code reference or sub name (see *Note Perlref: (perl.info)perlref,).

   `$cb_ref->Ptr()' then returns a function pointer.  C code that calls it
will end up calling `&some_sub'.

EXAMPLES
========

   This code loads and calls the math library function *sinh()*.  It
assumes that you have a dynamic version of the math library which will be
found by `DynaLoader::dl_findfile("-lm")'.  If this doesn't work, replace
`"-lm"' with the name of your dynamic math library.

     use C::DynaLib;
     $libm = new C::DynaLib("-lm");
     $sinh = $libm->DeclareSub("sinh", "d", "d");
     print "The hyperbolic sine of 3 is ", &{$sinh}(3), "\n";
     # The hyperbolic sine of 3 is 10.0178749274099

   The following example uses the C library's *strncmp()* to compare the
first n characters of two strings:

     use C::DynaLib;
     $libc = new C::DynaLib("-lc");
     $strncmp = $libc->DeclareSub("strncmp", "i", "p", "p", "I");
     $string1 = "foobar";
     $string2 = "foolish";
     $result = &{$strncmp}($string1, $string2, 3);  # $result is 0
     $result = &{$strncmp}($string1, $string2, 4);  # $result is -1

   The files test.pl and `README.win32' contain examples using callbacks.

CALLING CONVENTIONS
===================

   This section is intended for anyone who is interested in debugging or
extending this module.  You probably don't need to read it just to use the
module.

The problem
-----------

   The hardest thing about writing this module is to accommodate the
different calling conventions used by different compilers, operating
systems, and CPU types.

   "What's a calling convention?" you may be wondering.  It is how
compiler-generated functions receive their arguments from and make their
return values known to the code that calls them, at the level of machine
instructions and registers.  Each machine has a set of rules for this.
Compilers and operating systems may use variations even on the same
machine type.  In some cases, it is necessary to support more than one
calling convention on the same system.

   "But that's all handled by the compiler!" you might object.  True
enough, if the calling code knows the signature of the called function at
compile time.  For example, consider this C code:

     int foo(double bar, const char *baz);
     ...
     int res;
     res = foo(sqrt(2.0), "hi");

   A compiler will generate specific instruction sequences to load the
return value from *sqrt()* and a pointer to the string `"hi"' into
whatever registers or memory locations *foo()* expects to receive them in,
based on its calling convention and the types double and `char *'.
Another specific instruction sequence stores the return value in the
variable res.

   But when you compile the C code in this module, it must be general
enough to handle all sorts of function argument and return types.

   "Why not use varargs/stdarg?"  Most C compilers support a special set
of macros that allow a function to receive a variable number of arguments
of variable type.  When the function receiving the arguments is compiled,
it does not know with what argument types it will be called.

   But the code that *calls* such a function *does* know at compile time
how many and what type of arguments it is passing to the varargs function.
There is no "reverse stdarg" standard for passing types to be determined
at run time.  You can't simply pass a `va_list' to a function unless that
function is defined to receive a `va_list'.  This module uses
varargs/stdarg where appropriate, but the only appropriate place is in the
callback support.

The solution (well, half-solution)
----------------------------------

   Having failed to find a magic bullet to spare us from the whims of
system designers and compiler writers, we are forced to examine the
calling conventions in common use and try to put together some "glue" code
that stands a chance of being portable.

   In writing glue code (that which allows code written in one language to
call code in another), an important issue is reliability.  If we don't get
the convention just right, chances are we will get a core dump (protection
fault or illegal instruction).

   To write really solid Perl-to-C glue, we would have to use assembly
language and have detailed knowledge of each calling convention.  Compiler
source code can be helpful in this regard, and if your compiler can output
assembly code, that helps, too.

   However, this is Perl, Perl is meant to be ported, and assembly
language is generally not portable.  This module typically uses C
constructs that happen to work most of the time, as opposed to assembly
code that follows the conventions faithfully.

   By avoiding the use of assembly, we lose some reliability and
flexibility.  By loss of reliability, I mean we can expect crashes,
especially on untested platforms.  Lost flexibility means having
restrictions on what parameter types and return types are allowed.

   The code for all conventions other than `hack30' (described below)
relies on C's *alloca()* function.  Unfortunately, *alloca()* itself is
not standard, so its use introduces new portability concerns.  For `cdecl'
(the most general convention) Makefile.PL creates and runs a test program
to try to ferret out any compiler peculiarities regarding *alloca()*.  If
the test program fails, the default choice becomes `hack30'.

Supported conventions
---------------------

   `C::DynaLib' currently supports the parameter-passing conventions
listed below.  The module can be compiled with support for one or more of
them by specifying (for example) `DECL=cdecl' on Makefile.PL's
command-line.  If none are given, Makefile.PL will try to choose based on
your perl configuration and/or the results of running a test program.

   At run time, a calling convention may be specified using a
named-parameter form of `DeclareSub' (described above), or a default may
be used.  The first `DECL=...' supplied to Makefile.PL will be the default
convention.

   Note that the convention must match that of the function in the dynamic
library, otherwise crashes or incorrect results are likely to occur.

`cdecl'
     All arguments are placed on the stack in reverse order from how the
     function is invoked.  This seems to be the default for Intel-based
     machines and some others.

`sparc'
     The first 24 bytes of arguments are cast to an array of six ints.
     The remaining args (and possibly piece of an arg) are placed on the
     stack.  Then the C function is called as if it expected six integer
     arguments.  On a Sparc, the six "pseudo-arguments" are passed in
     special registers.

`alpha'
     This is similar to the `sparc' convention, but the pseudo-arguments
     have type long instead of int, and all arguments are extended to
     eight bytes before being placed in the array.  On the AXP, a special
     sequence of assembly instructions is used to ensure that any function
     parameters of type double are passed correctly.

`hack30'
     This is not really a calling convention, it's just some C code that
     will successfully call a function most of the time on a variety of
     systems.  All arguments are copied into an array of 6 long integers
     (or 30 if 6 is not enough).  The function is called as if it expected
     6 (or 30) long arguments.

     You will run into problems if the C function either (1) takes more
     arguments than can fit in the array, (2) takes some non-long arguments
     on a system that passes them differently from longs (but `cdecl'
     currently has the same flaw), or (3) cares if it is passed extra
     arguments (Win32 API functions crash because of this).

     Because of these problems, the use of `hack30' is recommended only as
     a quick fix until your system's calling convention is supported.

BUGS
====

   Several unresolved issues surround this module.

Portability
-----------

   The "glue" code that allows Perl values to be passed as arguments to C
functions is architecture-dependent.  This is because the author knows of
no standard means of determining a system's parameter-passing conventions
or passing arguments to a C function whose signature is not known at
compile time.

   Although some effort is made in Makefile.PL to find out how parameters
are passed in C, this applies only to the integer type (Perl's `I32', to
be precise).  Functions that recieve or return type double, for example,
may not work on systems that use floating-point registers for this
purpose.  Specialized code may be required to support such systems.

Robustness
----------

   Usually, Perl programs run under the control of the Perl interpreter.
Perl is extremely stable and can almost guarantee an environment free of
the problems of C, such as bad pointers causing memory access violations.
Some modules use a Perl feature called "XSubs" to call C code directly
from a Perl program.  In such cases, a crash may occur if the C or XS code
is faulty.  However, once the XS module has been sufficiently debugged,
one can be reasonably sure that it will work right.

   Code called through this module lacks such protection.  Since the
association between Perl and C is made at run time, errors due to
incompatible library interfaces or incorrect assumptions have a much
greater chance of causing a crash than with either straight Perl or XS
code.

Security
--------

   This module does not require special privileges to run.  I have no
reason to think it contains any security bugs (except to the extent that
the known bugs impact security).  However, when this module is installed,
Perl programs gain great power to exploit C code which could potentially
have such bugs.  I'm not really sure whether this is a major issue or not.

   I haven't gotten around to understanding Perl's internal tainting
interface, so taint-checking may not accomplish what you expect.  (See
*Note Perlsec: (perl.info)perlsec,)

Deallocation of Resources
-------------------------

   To maximize portability, this module uses the DynaLoader interface to
dynamic library linking.  DynaLoader's main purpose is to support XS
modules, which are loaded once by a program and not (to my knowledge)
unloaded.  It would be nice to be able to free the libraries loaded by
this module when they are no longer needed.  This will be impossible, as
long as DynaLoader provides no means to do so.

Literal and temporary strings
-----------------------------

   Before Perl 5.00402, it was impossible to pass a string literal as a
pointer-to-nul-terminated-string argument of a C function.  For example,
the following statement (incorrectly) produced the error `Modification of
a read-only value attempted':

     &$strncmp("foo", "bar", 3);

   To work around this problem, one must assign the value to a variable
and pass the variable in its place, as in

     &$strncmp($dummy1 = "foo", $dummy2 = "bar", 3);

Callbacks
---------

   Only a certain number of callbacks can exist at a time.  Callbacks can
mess up the message produced by die in the presence of nested evals.  The
Callback code uses global data, and is consequently not thread-safe.

Miscellaneous Bugs
------------------

   There are restrictions on what C data types may be used.  Using
argument types of unusual size may have nasty results.  The techniques
used to pass values to and from C functions are generally hackish and
nonstandard.  Assembly code would be more complete.  Makefile.PL does too
much.  I haven't yet checked for memory leaks.

TODO
====

   Rewrite using GNU ffcall.  Fiddle with autoloading so we don't have to
call DeclareSub all the time.  Mangle C++ symbol names.  Get Perl to
understand C header files (macros and function declarations) with enough
confidence to make them useful here.

LICENSE
=======

   Copyright (c) 1997, 2000 by John Tobey.  This package is distributed
under the same license as Perl itself.  There is no expressed or implied
warranty, since it is free software.  See the file README in the top level
Perl source directory for details.  The Perl source may be found at:

     http://www.perl.com/CPAN/src/5.0/

AUTHOR
======

   John Tobey, jtobey@john-edwin-tobey.org

SEE ALSO
========

   `perl(1)' in this node, `perlfunc(1)' in this node (for pack),
`perlref(1)' in this node, `sigtrap(3)' in this node, `DynaLoader(3)' in
this node, `perlxs(1)' in this node, `perlcall(1)' in this node.


