Coder Social home page Coder Social logo

class-generic's Introduction

NAME

Class::Generic - Make generic classes in Perl

SYNOPSIS

    package MyPackage;

    use Mojo::UserAgent;
    use Class::Generic;

    class HTTP {
        attr user_agent => Mojo::UserAgent->new;

        method fetch_link ($link) {
            $self->user_agent->get($link);
        }

        func say_hi {
            print "Say hi\n";
        }
    }

    # In another package...

    package MyOtherPackage;
    use MyPackage::HTTP;

    sub run {
        my $link = shift;

        my $http = MyPackage::HTTP->new;
        $http->fetch_link($link);
    }

DESCRIPTION

Class::Generic declares new keywords using Keyword::Declare and injects Moo and Method::Signatures code into your package.

All class declarations use the parent package as a prefix for the scaffolded Moo package. In the example above:

    package MyPackage;

    use Class::Generic;

sets the package prefix as MyPackage, so any class declaration afterwards are built as MyPackage::$class

METHODS

Class::Generic simply parses your module's code and replaces keywords with Moo and Method::Signatures code.

Class::Generic looks for two keywords in your code: class and attr.

class - looks for arguments in this order: name, extends, subclass, block. Extends and subclass are optional.

    class FooBar extends FooBaz {
        ...
    }

You can also use Python and Ruby style syntax:

    class FoobBar(FooBaz) {
        ...
    }
    
    class FooBar > FooBaz {
        ...
    }

Or, if you want, set your own custom extends:

    use Class::Generic;
    
    $Class::Generic::CUSTOM_EXTENDS = 'base';
    
    class Foobar base FooBaz {
        ...
    }

attr - looks for a AnonymousHash, AnonymousArray, ScalarVar, or AnonymousSubroutine and generates a rw attribute (with no type checking).

class Foobar {
    attr num        => 1;
    attr str        => 'hello world';
    attr user_agent => Mojo::UserAgent->new;
}

method - From Method::Signatures

func - From Method::Signatures

This will also inject a method TRACE into your code so you can see the generated code:

    my $http = MyPackage::HTTP->new;
    $http->TRACE;

A global var @TRACE keeps track of all the code and passes a scalar ref to Perl::Tidy where it's beautified and printed to STDOUT.

For example, this code:

    package Test;
    use Class::Generic;

    class TestClass_05 {
        method say_hello {
            print "Hello\n";
        }

        func say_hi {
            print "Say hi\n";
        }
    }

    ... (In another file)

    use Test::TestClass_05;

    Test::TestClass_05->new->TRACE;

Produces:

    package Test::TestClass_05 {
        use Moo;
        use Method::Signatures;

        extends 'Exporter';

        method TRACE {
            my $tidy = eval { require Perl::Tidy };

            if ($tidy) {
                Perl::Tidy::perltidy(
                    source => \(join '', @Class::Generic::TRACE),
                );
            }
            else {
                return (join '', \@Class::Generic::TRACE);
            }
        }

        method say_hello {
            print "Hello\n";
        }

        func say_hi {
            print "Say hi\n";
        }
    };    

EXAMPLE

    package API;

    use Class::Generic;

    class Error extends Throwable {}

    class Client {
        use Try::Tiny;
        use API::Error;
        use Mojo::UserAgent;

        attr user_agent => Mojo::UserAgent->new;

        method request_url($url) {
            my $resp;

            try {
                $resp = $self->user_agent->get($url);

                die $resp unless $resp->is_success;
            } catch {
                API::Error->throw({
                    message => "Failed to get url: $_"
                });
            };

            return $resp->content;
        }
    }

WHY?

I was Inspired by Damian Conway's Dios, but I wanted a minimalistic approach to implementing classes in Perl, without using scary sigils or Perl-specifc syntax (or what I like to refer to as "Python friendly").

This can also be used a learning tool, for those coming from Python and Ruby who want to understand how Perl's classes work.

AUTHOR

Connor Yates [email protected]

COPYRIGHT

Copyright 2017- Connor Yates

LICENSE

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

SEE ALSO

class-generic's People

Contributors

connoryates avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.