root/lang/perl/Shika/trunk/lib/Shika.pm @ 25075

Revision 25075, 3.1 kB (checked in by tokuhirom, 4 years ago)

updated todo list

Line 
1package Shika;
2
3use strict;
4use warnings;
5our $VERSION = '0.01';
6eval "use mro; 1;" or eval "use MRO::Compat; 1;";
7
8sub import {
9    my $pkg = caller(0);
10    strict->import;
11    warnings->import;
12
13    no strict 'refs';
14    *{"$pkg\::new"}     = \&_new;
15    *{"$pkg\::has"}     = \&_has;
16    *{"$pkg\::extends"} = \&_extends;
17    *{"$pkg\::with"} = \&_with;
18}
19
20my $default = {};
21
22sub _new {
23    my $class = shift;
24    my %attr = @_;
25
26    # set default values
27    for my $klass ($class, @{mro::get_linear_isa($class)}) {
28        while (my ($name, $code) = each %{$default->{$klass}}) {
29            unless (exists $attr{$name}) {
30                $attr{$name} = $code->();
31            }
32        }
33    }
34
35    bless { %attr }, $class
36}
37
38sub _has {
39    my $pkg = caller(0);
40    my $n = shift;
41    my %attr = @_;
42    no strict 'refs';
43    *{"$pkg\::$n"} = sub {
44        return $_[0]->{$n} if @_ == 1;
45        return $_[0]->{$n} = $_[1] if @_ == 2;
46        shift->{$n} = \@_;
47    };
48    if (my $handles = $attr{handles}) {
49        for my $handle (@$handles) {
50            *{"$pkg\::$handle"} = sub {
51                shift->$n->$handle(@_)
52            };
53        }
54    }
55    if (my $def = $attr{default}) {
56        $default->{$pkg}->{$n} = $def;
57    }
58}
59
60sub _extends {
61    my $pkg = caller(0);
62    my @parents = @_;
63    no strict 'refs';
64    unshift @{"$pkg\::ISA"}, @parents;
65}
66
67sub _with {
68    my $pkg = caller(0);
69    my @roles = @_;
70
71    for my $role (@roles) {
72        eval "require $role" unless $role->can('meta');## no critic ### too bad
73        next unless $role->can('meta');
74
75        for my $method (@{ _get_functions($role) }) {
76            next if $method eq 'has' || $method eq 'requires' || $method eq 'meta';
77            next if $pkg->can($method);
78            no strict 'refs';
79            *{"$pkg\::$method"} = *{"$role\::$method"};
80        }
81    }
82}
83
84# copied from Class::Inspector
85sub _get_functions {
86    my $name = shift;
87
88    no strict 'refs';
89    # Get all the CODE symbol table entries
90    my @functions = sort grep { /\A[^\W\d]\w*\z/o }
91        grep { defined &{"${name}::$_"} }
92            keys %{"${name}::"};
93    \@functions;
94}
95
961;
97__END__
98
99=head1 NAME
100
101Shika - Lightweight class builder with DSL
102
103=head1 SYNOPSIS
104
105  package Point;
106  use Shika; # automatically turns on strict and warnings
107
108  has 'x';
109  has 'y';
110
111  sub clear {
112      my $self = shift;
113      $self->x(0);
114      $self->y(0);
115  }
116
117  package Point3D;
118  use Shika;
119
120  extends 'Point';
121
122  has 'z';
123
124  after 'clear' => sub {
125      my $self = shift;
126      $self->z(0);
127  };
128
129=head1 DESCRIPTION
130
131Shika is
132
133=head1 AUTHOR
134
135tokuhirom
136
137yappo
138
139lestrrat
140
141typester
142
143charsbar
144
145miyagawa
146
147kan
148
149walf443
150
151kazuho
152
153hidek
154
155mattn
156
157=head1 TODO
158
159    - coerce
160    - method modifiers
161    - role support
162    - isa?
163    - set default value lazily
164
165=head1 SEE ALSO
166
167=head1 REPOSITORY
168
169  svn co http://svn.coderepos.org/share/lang/perl/Shika/trunk Shika
170
171Shika is Subversion repository is hosted at L<http://coderepos.org/share/>.
172patches and collaborators are welcome.
173
174=head1 LICENSE
175
176This library is free software; you can redistribute it and/or modify
177it under the same terms as Perl itself.
178
179=cut
Note: See TracBrowser for help on using the browser.