Alien-Taco

 view release on metacpan or  search on metacpan

lib/Alien/Taco/Server.pm  view on Meta::CPAN

# Taco Perl server module.
# Copyright (C) 2013-2014 Graham Bell
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

=head1 NAME

Alien::Taco::Server - Taco Perl server module

=head1 SYNOPSIS

    use Alien::Taco::Server;
    my $server = new Alien::Taco::Server();
    $server->run();

=head1 DESCRIPTION

This module provides a Perl implementation of the actions
required of a Taco server.

=cut

package Alien::Taco::Server;

use Scalar::Util qw/blessed/;

use Alien::Taco::Transport;
use Alien::Taco::Util qw/filter_struct/;

use strict;

our $VERSION = '0.003';

=head1 SUBROUTINES

=head2 Main Methods

=over 4

=item new()

Set up a L<Alien::Taco::Transport> object communicating via
C<STDIN> and C<STDOUT>.

C<STDERR> is selected as the current stream to try to avoid
any subroutine or method calls printing to C<STDOUT> which would
corrupt communications with the client.

=cut

sub new {
    my $class = shift;

    # Create cache of objects held on the server side for which an
    # object number is passed to the client.

    my $self = bless {
        nobject => 0,
        objects => {},
    }, $class;

    # Select STDERR as current file handle so that if a function is
    # called which in turn prints something, it doesn't go into the
    # transport stream.

lib/Alien/Taco/Server.pm  view on Meta::CPAN

}

=item get_class_attribute($message)

Attempt the read a variable from the given class's package.
The attribute name should begin with the appropriate sigil
(C<$> / C<@> / C<%>).

=cut

sub get_class_attribute {
    my $self = shift;
    my $message = shift;

    my $name = $message->{'name'};

    # Construct full name from sigil + class + '::' + attribute.
    return $self->_get_attr_or_value(
        substr($name, 0, 1) . $message->{'class'} . '::' . substr($name, 1));
}

=item get_value($message)

Try to read the given variable.  The variable name should begin
with the appropriate sigil (C<$> / C<@> / C<%>).

=cut

sub get_value {
    my $self = shift;
    my $message = shift;

    return $self->_get_attr_or_value($message->{'name'});
}

# _get_attr_or_value($name)
#
# Internal method to get a value based on its sigil.

sub _get_attr_or_value {
    my $self = shift;
    my $name = shift;

    no strict 'refs';
    if ($name =~ s/^\$//) {
        return _make_result($$name);
    }
    elsif ($name =~ s/^\@//) {
        return _make_result(\@{$name});
    }
    elsif ($name =~ s/^\%//) {
        return _make_result(\%{$name});
    }
    else {
        die 'unknown sigil';
    }
}

=item import_module($message)

Convert the supplied module name to a path by replacing C<::> with C</>
and appending C<.pm>.  Then require the resulting module file and
call its C<import> subroutine.  Any parameters provided are passed
to C<import>.

=cut

sub import_module {
    my $self = shift;
    my $message = shift;
    my @param = _get_param($message);

    my $m = $message->{'name'};
    my $f = $m; $f =~ s/::/\//g;

    require $f . '.pm';
    $m->import(@param);

    return $null_result;
}

=item set_attribute($message)

Attempt to set an attribute of an object, but see the notes for
C<get_attribute> above.

=cut

sub set_attribute {
    my $self = shift;
    my $message = shift;

    my $number = $message->{'number'};
    my $name = $message->{'name'};
    my $value = $message->{'value'};

    my $object = $self->_get_object($number);

    die 'object is not a hash' unless $object->isa('HASH');

    $object->{$name} = $value;

    return $null_result;
}

=item set_class_attribute($message)

Attempt to set a variable in the given class's package.
The attribute name should begin with the appropriate sigil
(C<$> / C<@> / C<%>).

=cut

sub set_class_attribute {
    my $self = shift;
    my $message = shift;

    my $name = $message->{'name'};

    # Construct full name from sigil + class + '::' + attribute.
    $self->_set_attr_or_value(



( run in 1.347 second using v1.01-cache-2.11-cpan-df04353d9ac )