Locale::Object::Currency::Converter - convert between currencies


Locale-Object documentation Contained in the Locale-Object distribution.

Index


Code Index:

NAME

Top

Locale::Object::Currency::Converter - convert between currencies

DESCRIPTION

Top

Locale::Object::Currency::Converter allows you to convert between values of currencies represented by Locale::Object::Currency objects.

SYNOPSIS

Top

    use Locale::Object::Currency;
    use Locale::Object::Currency::Converter;

    my $usd = Locale::Object::Currency->new( code => 'USD' );
    my $gbp = Locale::Object::Currency->new( code => 'GBP' );
    my $eur = Locale::Object::Currency->new( code => 'EUR' );
    my $jpy = Locale::Object::Currency->new( code => 'JPY' );

    my $converter = Locale::Object::Currency::Converter->new(
                                                from    => $usd,
                                                to      => $gbp,
                                                service => 'XE'
                                               );

    my $result    = $converter->convert(5);
    my $rate      = $converter->rate;
    my $timestamp = $converter->timestamp;

    print $converter->use_xe;
    print $converter->use_yahoo;

    $converter->from($eur);
    $converter->to($jpy);
    $converter->service('Yahoo');

    $converter->refresh;

PREREQUISITES

Top

This module requires Finance::Currency::Convert::XE and Finance::Currency::Convert::Yahoo.

METHODS

Top

new()

    my $converter = Locale::Object::Currency::Converter->new();

Creates a new converter object. With no arguments, creates a blank object. Possible arguments are from, to and service, all or none of which may be given. from and to must be Locale::Object::Currency objects. service must be one of either 'XE' or 'Yahoo', to specify the conversion should be done by http://xe.com/ucc/ or http://finance.yahoo.com/ respectively.

use_xe()

    print $converter->use_xe;

Returns 1 or 0 depending on whether a use Finance::Currency::Convert::XE; was successful. If 1, you can do conversions using the XE.com service.

use_yahoo()

    print $converter->use_yahoo;

Returns 1 or 0 depending on whether a use Finance::Currency::Convert::Yahoo; was successful. If 1, you can do conversions using the finance.yahoo.com service.

from()

    $converter->from($eur);

Sets a currency to do conversions from. Takes a Locale::Object::Currency object.

to()

    $converter->to($jpy);

Sets a currency to do conversions to. Takes a Locale::Object::Currency object.

service()

    $converter->service('Yahoo');

Sets which currency conversion service to use. Depends on two other modules; see use_xe() and use_yahoo() above.

convert()

    my $result = $converter->convert(5);

Does the currency conversion. Takes a numeric argument representng the amount of the 'from' currency to convert into the 'to' currency, gives the result. Will croak if you didn't select a conversion service, 'from' and 'to' currency when you did new() or afterwards with the associated methods (see above).

rate()

    my $rate = $converter->rate;

Returns the conversion rate between your 'from' currency and your 'to' currency, as of the time you last did a conversion. If you haven't done any conversions yet, will do one first (the result for converting 1 unit of a currency into another currency is the rate) and give you that.

timestamp()

    my $timestamp = $converter->timestamp;

Returns the time timestamp of the last time the currency exchange rate was stored, either the last time you did a convert() or a refresh().

refresh()

    $converter->refresh;

Will update the stored conversion rate and timestamp by doing another conversion. Doesn't return anything.

AUTHOR

Top

Earle Martin <hex@cpan.org>

http://downlode.org/Code/Perl/

CREDITS

Top

See the credits for Locale::Object.

LEGAL

Top


Locale-Object documentation Contained in the Locale-Object distribution.

package Locale::Object::Currency::Converter;

use strict;
use warnings;;
use Carp;

use Scalar::Util qw(looks_like_number);

our $VERSION = '0.78';

my ($use_xe, $xe_error, $use_yahoo, $yahoo_error);

# Check if we have the two modules that actually do the work of conversions.
eval {
  require Finance::Currency::Convert::XE;
};

if ($@)
{
  $use_xe   = 0;
  $xe_error = $@;
}
else
{
  $use_xe = 1;
}

eval {
  require Finance::Currency::Convert::Yahoo;
};

if ($@)
{
  $use_yahoo   = 0;
  $yahoo_error = $@;
}
else
{
  $use_yahoo = 1;
}


sub new
{
  my $class = shift;
  my %params = @_;

  my $self = bless {}, $class;
  
  # Initialize the new object or return an existing one.
  $self->init(%params);
}

# Initialize the object.
sub init
{
  my $self   = shift;
  my %params = @_;
  
  # Make a hash of valid parameters.
  my %allowed_params = map { $_ => undef }
    qw(service from to);

  foreach my $key (keys %params)
  {
    # Go no further if the specified parameter wasn't one.
    croak "Error: You can only specify a service to use and currencies to convert between for initialization." unless exists $allowed_params{$key};
  }

  # Set an attribute of the chosen currency conversion service.
  if ($params{service})
  {
    croak "Error: Values for service can be 'XE' or 'Yahoo'; you said $params{service}." unless $params{service} =~ /^Yahoo$|^XE$/;
    
    $self->{service} = $params{service};
  }
  
  # Set an attribute of the currency to convert from.
  if ($params{from})
  {
    croak "Error: you can only use a Locale::Object::Currency object to convert from." unless $params{from}->isa('Locale::Object::Currency');
    
    $self->{from} = $params{from};
  }

  # Set an attribute of the currency to convert to.
  if ($params{to})
  {
    croak "Error: you can only use a Locale::Object::Currency object to convert from." unless $params{to}->isa('Locale::Object::Currency');

    $self->{to} = $params{to};
  }
  
  # Return the object.
  $self;
}

# Set currency service to be used.
sub service
{
  my $self = shift;
  my $service = shift;
  
  # Be generous in what we accept.
  $service = lc($service);
    
  if ($service eq 'xe')
  {
    # Check that we can use Finance::Currency::Convert::XE.
    if ($use_xe == 1)
    {
      return $self;
    }
    else
    {
      carp "WARNING: Cannot set service to XE: $xe_error";
    }
  }
  elsif ($service eq 'yahoo')
  {
    # Check that we can use Finance::Currency::Convert::Yahoo.
    if ($use_yahoo == 1)
    {
      return $self;
    }
    else
    {
      carp "WARNING: Cannot set service to Yahoo: $yahoo_error";
    }
  }
  else
  {
    carp "ERROR: Values for service can be 'XE' or 'Yahoo' (case-insensitive); you said '$service'.";
  }
  
  $self->{service} = $service;
}

# Set currency to be converted from.
sub from
{
  my $self = shift;
  my $from = shift;

  croak "Error: you can only use a Locale::Object::Currency object to convert from." unless $from->isa('Locale::Object::Currency');
    
  $self->{from} = $from;
}

# Set currency to converted to.
sub to
{
  my $self = shift;
  my $to   = shift;

  croak "Error: you can only use a Locale::Object::Currency object to convert to." unless $to->isa('Locale::Object::Currency');
    
  $self->{to} = $to;

}

# Do currency conversions.
sub convert
{
  my $self = shift;
  my $value = shift;
  
  # Test if $value is numeric with Scalar::Util.
  croak "Error: Argument '$value' to convert not numeric" unless looks_like_number($value);

  croak "Error: No currency set to convert from" unless $self->{from};
  croak "Error: No currency set to convert to" unless $self->{to};
  croak "Error: No service specified for conversion" unless $self->{service};

  my $result;
  
  if ($self->{service} eq 'Yahoo')
  {
    $result = _yahoo($self, $value);
  }
  elsif ($self->{service} eq 'XE')
  {
    $result = _xe($self, $value);
  }
  
  $result;
}

# Internal method to do Yahoo! currency conversions.
sub _yahoo
{
  my $self  = shift;
  my $value = shift;
  
  # We're not in a talkative mood.
  $Finance::Currency::Convert::Yahoo::CHAT = undef;

  my $result;
  
  eval {
    $result = Finance::Currency::Convert::Yahoo::convert($value,$self->{from}->code,$self->{to}->code);
  };
  
  return "ERROR: $!" if $! ne '';
  
  $result;
}

# Internal method to do XE currency conversions.
sub _xe
{
  my $self = shift;
  my $value = shift;

  my $xe = Finance::Currency::Convert::XE->new() or croak "Error: Couldn't create Finance::Currency::Convert::XE object: $!";

  my $result;

  eval
  {
    $result = $xe->convert(
                           'source' => $self->{from}->code,
                           'target' => $self->{to}->code,
                           'value'  => $value
                          );
  };
  
  return "ERROR: $!" if $! ne '';
  
  $result;
}

# Give the exchange rate of the currencies.
sub rate
{
  my $self = shift;

  # If there's no rate stored, set one.
  $self->refresh unless $self->{_rate};

  return $self->{_rate};
}

# Give the time that the rate was stored.
sub timestamp
{
  my $self = shift;
 
  if ($self->{_timestamp})
  {
    return $self->{_timestamp};
  }
  else
  {
    return undef;
  }
}

# Update the exchange rate.
sub refresh
{
  my $self = shift;

  # Do a conversion to get the rate.
  my $rate = $self->convert(1);

  # Make a note of the rate and the time.
  $self->{_rate}      = $rate;
  $self->{_timestamp} = time;  
}

# Can you use Finance::Currency::Convert::XE?
sub use_xe
{
  $use_xe;
}

# Can you use Finance::Currency::Convert::Yahoo?
sub use_yahoo
{
  $use_yahoo;
}


1;

__END__