SlideShare a Scribd company logo
1 of 35
Download to read offline
Moo in practice - App::Math::Tutor
Jens Rehsack
Niederrhein Perl Mongers
2014-2015
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 1 / 41
Introduction Motivation
Motivation
Moo and App::Math::Tutor
real world examples over far-fetched conceptuals
MooX::Cmd, MooX::Options and MooX::ConfigFromFile provide way more
features and flexibility than either
◮ App::Cmd with Getopt::Long::Descriptive
◮ MooseX::App::Cmd along with corresponding MooseX wrappers around
related stuff
2nd
generation of modern OO in Perl5
App::Math::Tutor
Allow parents help their children improving their mathematical skills
Add support for exercise types as children require
provide extensible design to allow easy augment of exercise
Goal: Improve to Web-Service, eg. by mapping MooX::Cmd to URI path and
MooX::Options to GET parameters
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 3 / 41
Introduction Audience
Audience
Audience
Developers who want to create or improve Perl5 software
Developers who want to learn how to develop modern OO with Perl5
Developers who are interested in developing mathematical exercises
Prerequisites of the Audience
Following knowledge is expected:
General knowledge about object oriented programming or concepts like
◮ classes
◮ objects
◮ polymorphism, inheritance and/or roles
◮ methods, class functions
◮ attributes, properties
slightly above basic Perl experience
ever heard of Smalltalk and its OO-concept is a strong bonus
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 4 / 41
Modules Classes and Roles
Classes in Moo
classes can be instantiated
one can inherit from classes
one can aggregate classes
distinguish naming conflicts is up to developer
{
package Natural;
use Moo;
sub _stringify { ... };
}
{
package Roman;
use Moo;
extends "Natural";
sub _stringify { ... };
}
my $natnum = Natural ->new( value => 42 ); say $natnum ->_stringify (); # 42
my $romnum = Roman ->new( value => 42 ); say $romnum ->_stringify (); # XLII
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 6 / 41
Modules Classes and Roles
Roles in Moo
roles describe a dedicated behavior (e.g. printable)
roles can be composed into classes
one can’t inherit from roles - only consume
roles cannot exist stand-alone
roles are consumed once
naming conflicts cause compile time error
{ package Printable;
use Moo:: Role; # now it’s a role - no ’is a’ relationship anymore
sub print { my $self = shift; say $self ->_stringify }
}
{ package Natural;
use Moo; # class
with "Printable"; # consumes a role
sub _stringify { ... };
}
my $natnum = Natural ->new( value => 42 ); $natnum ->print; # 42
my $romnum = Roman ->new( value => 42 ); $romnum ->print; # XLII
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 7 / 41
Attributes Attributes in Moo
Attributes in Moo
package VulFrac;
use Moo;
has nume rator => ( is => "ro", required => 1 );
has denom inator => ( is => "ro", required => 1 );
1;
use ”has” keyword to define a attribute
attributes ”numerator” and ”denominator”
attributes are immutable and required
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 8 / 41
Attributes Attribute Options
Attribute options - Selection I
is mandatory behavior description
ro defines the attribute is read-only
rw defined the attribute is read/writable
lazy defines the attribute is read-only with a lazy
initialization, implies builder => 1
required when set to a true value, attribute must be passed on instantiation
init arg Takes the name of the key to look for at instantiation time of the
object. A common use of this is to make an underscored attribute
have a non-underscored initialization name. undef means that
passing the value in on instantiation is ignored.
isa defines a subroutine (coderef) which is called to validate values to
set
coerce defines a subroutine (coderef) which forces attribute values
default subroutine (coderef) which is called to initialize an attribute
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 9 / 41
Attributes Attribute Options
Attribute options - Selection II
Following options can benefit from attribute shortcuts: the value of 1 instead of a
method name means to generate a coderef which calls the method
${option name} ${attr name}
builder takes a method name (string) which is called to initialize an
attribute (calls build ${attr name} on attribute shortcut)
trigger takes a subroutine (coderef) which is called anytime the attribute
is set (calls trigger ${attr name} on attribute shortcut)
clearer takes a method name (string) which will clear the attribute
(provides clear ${attr name} on attribute shortcut)
predicate takes a method name (string) which will return true if an
attribute has a value (provides has ${attr name} on attribute
shortcut)
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 10 / 41
Methods Method Examples
Methods in Moo I
package VulFrac;
use Moo;
use overload ’""’ => " _stringify",
’0+’ => "_numify",
’bool ’ => sub { 1 },
’<=>’ => " _num_compare";
has numerator => ( is => "ro", required => 1 );
has denominator => ( is => "ro", required => 1,
isa => sub { $_ [0] != 0 or die "Not != 0" };
sub _stringify { my $self = shift;
return sprintf(" frac {%s}{%s}",
$self ->numerator , $self -> denominator ); }
sub _numify { $_[0]-> numerator / $_[0]-> denominator ; }
...
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 11 / 41
Methods Method Examples
Methods in Moo II
package Rationale;
use Moo;
extends "VulFrac";
has digits => ( is => "ro", required => 1 );
sub _stringify {
my $digits = $_[0]-> digits;
sprintf("%.${digits}g", $_[0]-> _numify ); }
nothing like MooseX::Declare - pure Perl5 keywords are enough for plain
methods
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 12 / 41
Methods Method Modifiers
Method Modifiers
Method modifiers are a convenient feature from the CLOS (Common Lisp Object
System) world:
before before method(s) => sub { ...}
before is called before the method it is modifying. Its return value
is totally ignored.
after after method(s) => sub { ...}
after is called after the method it is modifying. Its return value is
totally ignored.
around around method(s) => sub { ...}
around is called instead of the method it is modifying. The method
you’re overriding is passed as coderef in the first argument.
- No support for super, override, inner or augment
In doubt MooX::Override provides override and super while MooX::Augment
provides augment and inner
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 13 / 41
Methods Method Modifiers
Method Modifiers - Advantages
supersedes $self->SUPER::foo(@ ) syntax
cleaner interface than SUPER
allows multiple modifiers in single namespace
also possible from within roles and not restricted to inheritance
ensures that inherited methods invocation happens right (mostly - remember
around)
no need to change packages
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 14 / 41
Methods Method Modifiers
Methods Modifiers - around avoid calling $orig
package App:: Math :: Tutor :: Role :: Roman;
use Moo:: Role;
with "App:: Math :: Tutor :: Role :: Natural";
{ package RomanNum;
use Moo;
extends "NatNum"; # derives overloading !
sub _stringify { ... } }
around " _guess_natural_number" => sub {
my $orig = shift;
my $max_val = $_[0]-> format;
my $value = int( rand( $max_val - 1 ) ) + 1;
return RomanNum ->new( value => $value );
};
captures control
receives responsibility
runtime of modified method completely eliminated
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 15 / 41
Methods Method Modifiers
Methods Modifiers - around modifying $orig return value
package App:: Math :: Tutor :: Role :: Roman;
use Moo:: Role;
with "App:: Math :: Tutor :: Role :: Natural";
{ package RomanNum;
use Moo;
extends "NatNum"; # derives overloading !
sub _stringify { ... } }
around " _guess_natural_number" => sub {
my $orig = shift;
my $num = $orig ->(@_);
return RomanNum ->new( value => $num ->value );
};
modifies only required part
leaves most responsibility in modified method
runtime of modified method added to this method’s runtime
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 16 / 41
Structure Frontend
Frontend (dictated by MooX::Cmd)
App::Math::Tutor
App::Math::Tutor::Cmd::VulFrac
App::Math::Tutor::Cmd::VulFrac::Cmd::Add
App::Math::Tutor::Cmd::VulFrac::Cmd::Mul
App::Math::Tutor::Cmd::VulFrac::Cmd::Cast
App::Math::Tutor::Cmd::Natural
App::Math::Tutor::Cmd::Natural::Cmd::Add
App::Math::Tutor::Cmd::Natural::Cmd::Mul
App::Math::Tutor::Cmd::Roman
App::Math::Tutor::Cmd::Roman::Cmd::Add
App::Math::Tutor::Cmd::Roman::Cmd::Cast
App::Math::Tutor::Cmd::Unit
App::Math::Tutor::Cmd::Unit::Cmd::Add
App::Math::Tutor::Cmd::Unit::Cmd::Mul
App::Math::Tutor::Cmd::Unit::Cmd::Cast
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 18 / 41
Structure CLI Concept
Exercise Groups
App::Math::Tutor::Cmd::VulFrac Exercises in vulgar fraction calculation
App::Math::Tutor::Cmd::Natural Exercises in calculations using natural numbers
App::Math::Tutor::Cmd::Roman Exercises in calculations using natural numbers,
but show them using roman number encoding (exercises and
solutions)
App::Math::Tutor::Cmd::Unit Exercises in calculations using units (times,
currency, . . . )
App::Math::Tutor::Cmd::Power Exercises in calculations of power mathematics
App::Math::Tutor::Cmd::Polynom Exercises for polynomial mathematics (Zero of
a function, Vertex, . . . )
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 19 / 41
Design Simple Exercise
Typical Exercise design
App::Math::Tutor::Cmd::VulFrac::Cmd::Add
build exercise() : exercise
App::Math::Tutor::Role::VulFracExercise
format
App::Math::Tutor::Role::VulFrac
check vulgar fraction() : bool
guess vulgar fraction() : VulFrac
get vulgar fractions() : [ VulFrac ]
VulFrac
num
denum
stringify() : Str
numify() : Num
num compare() : Int
euklid() : Int
gcd() : Int
reduce() : VulFrac
reciprocal() : VulFrac
App::Math::Tutor::Role::Exercise
exercise : lazy
# { section, caption, label,
# header, challenges, solutions }
output name : lazy
template filename : lazy
build exercise() = 0 : exercise
build output name() : Str
build template filename() = 0 : Str
execute()
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 20 / 41
Design Derived Exercise
Derived Exercise design
App::Math::Tutor::Cmd::Roman::Cmd::Add
build exercise() : exercise
App::Math::Tutor::Role::NaturalExercise
format
App::Math::Tutor::Role::Roman
around => guess natural number() : Roman
App::Math::Tutor::Role::Natural
check natural number() : bool
guess natural number() : Natural
get natural number() : [ Natural ]
RomanNum
stringify() : Str
Natural
value
stringify() : Str
numify() : Num
num compare() : Int
App::Math::Tutor::Role::Exercise
exercise : lazy
# { section, caption, label,
# header, challenges, solutions }
output name : lazy
template filename : lazy
build exercise() = 0 : exercise
build output name() : Str
build template filename() = 0 : Str
execute()
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 21 / 41
Improvements Design
Improving design
introduce factories
add lazy factory attribute (allowes overriding factory to use by around’ing
builder)
separate number classes (type system, but no MooseX::Types)
approval for reasonable exercise value should be part of factory
approval for valid number should be coerced (trigger?)
Design history
I started with just vulgar fraction exercises
Design covered exactly those needs
Design future
Modern Perl-OO allowes easy refactoring to apply above improvements
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 22 / 41
MooX General purpose eXtensions
MooX in general
Some Moo extensions for getting a picture - the list is neither complete nor is it
intended to be
MooX Distributions
MooX::Log::Any logging role building a very lightweight wrapper to Log::Any
MooX::Validate minimalist Data Validation for Moo
MooX::Types::MooseLike Moose like types for Moo
MooX::Override adds ”override method => sub . . . ” support to Moo
MooX::Augment adds ”augment method => sub . . . ” support to Moo
MooX::late easily translate Moose code to Moo
MooX::PrivateAttributes create attribute only usable inside your package
MooX::Singleton turn your Moo class into singleton
MooX::Aliases easy aliasing of methods and attributes in Moo
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 24 / 41
MooX CLI related eXtensions
MooX Distributions for CLI
MooX::Cmd
giving an easy Moo style way to make command organized CLI apps
support sub-commands with separated options when used together with
MooX::Options
MooX::Options
explicit Options eXtension for Object Class
no mess with composed attributes
MooX::ConfigFromFile
Moo eXtension for initializing objects from config file
RC files with structures (JSON, INI, YAML, XML, ...)
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 25 / 41
MooX CLI related eXtensions
General CLI Construction Flow
:main :MooX::Cmd :MooX::Options :MooX::ConfigFromFile :Moo
new with cmd()
buildcommand
commands()
splitargv
new with options()
parse
options
new()
BUILDARGS()
super->BUILDARGS()
buildloaded
config
helpon
exception
execute
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 26 / 41
Provided Framework Exercise Role
package App:: Math :: Tutor :: Role :: Exercise;
use strictures; # instead of strict + warnings
use Moo:: Role; use MooX :: Options;
option quantity => (
is => "ro",
doc => "Specifies number of exercises to generate",
long_doc => "Specify number of exercises to generate. "
. "In case of several kind of ...",
format => "i",
short => "n",
default => sub { 15 },
);
has output _name => ( is => "lazy" );
sub _build_output_name {
join( "", map { $_ -> command_name || "" } @{ $_[0]-> command_chain } );
}
being a role (no ”is a” relationship) and add CLI options capabilities
defining an attribute which will be initialized by command line
support MooX::Option’s --man usage feature
attribute for output file to generate — lazy to allow provide individual
name builder
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 28 / 41
Provided Framework Exercise Role
has exercises => ( is => "lazy" );
sub execute {
my $exercises = $_[0]->exercises;
my $ttcpath = File ::Spec ->catfile(
File :: ShareDir :: dist_dir("App -Math -Tutor"),
$_[0]-> template_filename . ".tt2" );
my $template = Template ->new( { ABSOLUTE => 1 });
my $rc = $template ->process( $ttcpath , {
exercises => $exercises ,
output => { format => ’pdf’ },
},
$_[0]-> output_name . ’.pdf’);
$rc or croak( $template ->error () );
return 0;
}
attribute containing the exercises definitions, exercises itself and their
solutions (depending on template) — lazy implies requires
’’ build exercises’’
method to satisfy MooX::Cmd
fetch exercises definition implies calling build exercises
build full qualified path of template file name residing in app’s share
directory, instantiate template processor and run it
force output format ”pdf” (Template::LaTeX will be instructed by template)
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 29 / 41
Provided Framework Vulgar Fraction Exercise Role
package App:: Math :: Tutor :: Role ::Vul FracExercise;
use strictures; use Moo:: Role; use MooX :: Options;
with "App:: Math :: Tutor :: Role :: Exercise", "App:: Math :: Tutor :: Role :: VulFrac";
option format => (
is => "ro",
doc => "specifies format of numerator/ denominator ",
long_doc => "Allow specifying the format of the numerator/ denominator ...",
isa => sub { defined( $_[0] ) and !ref $_[0]
and $_ [0] !~ m ,^d?n+(?:/d?n+)?$, and die("Invalid format");
},
coerce => sub { ...
my ( $fmta , $fmtb ) = ( $_[0] =~ m ,^(d?n+)(?:/(d?n+))?$, );
$fmtb //= $fmta;
my $starta = "1"; my $startb = "1";
$fmta =~ s/^(d)(.*)/ $2/ and $starta = $1;
$fmtb =~ s/^(d)(.*)/ $2/ and $startb = $1;
[ $starta . "0" x length($fmta), $startb . "0" x length($fmtb) ]
},
default => sub { return [ 100, 100 ]; }, format => "s",
);
be a nice package ˆWrole, intending to provide command line options for
instantiation
compose role behavior using Exercise and VulFrac
define option coercing option string into array ensuring the array ref as value
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 30 / 41
Create Exercise Preamble
package App:: Math :: Tutor :: Cmd:: VulFrac ::Cmd :: Add;
use strictures;
use Moo;
use MooX :: Cmd;
use MooX :: Options;
has template_filename => ( is => "ro",
default => "twocols");
with "App:: Math :: Tutor :: Role :: VulFracExercise ";
$ mtut vulfrac add
we’re of course a nice class
satisfy requirement of Exercise role: provide template filename – two column
template (for addition and substraction)
compose role ...VulFracExercise
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 31 / 41
Create Exercise Create Exercise Numbers
sub _build_exercises {
my ($self) = @_;
my (@tasks );
foreach my $i ( 1 .. $self ->amount ) {
my @line;
for ( 0 .. 1 ) { # 0: +, 1: -
my ( $a , $b ) = $self -> get_vulgar_fractions (2);
push @line , [ $a , $b ];
}
push @tasks , @line;
}
my $exercises = ...;
return $exercises;
}
exercise builder has to be provided by individual exercise
hold tasks of the exercise sheet
how many tasks per sheet? (remember the option in ...Role::Exercise)
a ”+” and a ”-” exercise per line
invoke factory per task
safe each line for processing
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 32 / 41
Create Exercise Format Challenge / Solution
my $exercises = {
section => "Vulgar fraction addition / subtraction ",
caption => ’Fractions ’,
label => ’vulgar_fractions_addition ’,
header => [ [ ’Vulgar Fraction Addition ’, ’Vulgar Fraction Su
challenges => [], solutions => [],
};
foreach my $line (@tasks) {
my ( @solution , @challenge );
foreach my $i ( 0 .. 1 ) {
my ( $a , $b , @way ) = @{ $line ->[$i] }; my $op = $i ? ’-’ : ’+’;
$op eq ’-’ and $a < $b and ( $b , $a ) = ( $a , $b );
push @challenge , sprintf( ’$ %s %s %s = $’, $a , $op , $b );
push @way , sprintf( ’%s %s %s’, $a , $op , $b );
...
}
push( @{ $exercises ->{ challenges} }, @challenge );
push( @{ $exercises ->{ solutions} }, @solution );
}
create exercise structure containing challenges and solutions
loop over created tasks and exercises per line
format challenge using operator ’""’ of VulFrac objects
same (but different) opening ”way” and remember the little thingies . . .
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 33 / 41
Create Exercise Format Solutions
sub _build_exercises {
( $a , $b ) = ( $a ->_reduce , $b = $b ->_reduce );
push @way , sprintf( ’%s %s %s’, $a , $op , $b )
if ( $a ->num != $line ->[$i]->[0]->num or $b ->num != ... );
my $gcd = VulFrac ->new( num => $a ->denum , denum => $b ->denum )->_gcd;
my ( $fa , $fb ) = ( $b ->{ denum} / $gcd , $a ->{ denum} / $gcd );
push @way , sprintf( ’frac {%d cdot %d}{%d cdot %d} %s ...’,
$a ->num , $fa , $a ->denum , $fa , $op , $b ->num , $fb , ... );
push @way , sprintf( ’frac {%d}{%d} %s frac {%d}{%d}’,
$a ->num*$fa , $a ->denum*$fa , $op , $b ->num*$fb , $b ->denum*$fb );
push @way , sprintf( ’frac {%d %s %d}{%d}’,
$a ->num * $fa , $op , $b ->num * $fb , $a ->denum * $fa );
my $s = VulFrac ->new( denum => $a ->denum * $fa ,
num => $i ? $a ->num * $fa - $b ->num * $fb : ...s/ -/+/);
push @way , "" . $s; my $c = $s ->_reduce; $c ->num != $s ->num and push @way , "
$c ->num > $c ->denum and $c ->denum > 1 and push @way , $c ->_stringify(1);
push( @solution , ’$ ’ . join( " = ", @way ) . ’ $’ );
}
try to reduce operands and add them to opening when successful
World of Handcraft: show calculation method by determine
geatest common divisor of operands denominator, format subsequent steps to
reach the solution
remark possible reducing, mixed fraction, cord it and go ahead
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 34 / 41
Created Exercise Output Challenges
Vulgar Fraction Addition Vulgar Fraction Subtraction
99
67
+ 43
84
= 45
41
− 32
48
=
19
7
+ 16
54
= 51
47
− 49
65
=
38
82
+ 38
99
= 56
33
− 30
32
=
96
80
+ 46
39
= 49
79
− 29
82
=
72
68
+ 46
99
= 42
49
− 38
59
=
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 35 / 41
Created Exercise Output Solutions
Vulgar Fraction Addition Vulgar Fraction Subtraction
99
67
+ 43
84
= 99·84
67·84
+ 43·67
84·67
= 8316
5628
+ 2881
5628
=
8316+2881
5628
= 11197
5628
= 15569
5628
45
41
− 32
48
= 45
41
− 2
3
= 45·3
41·3
− 2·41
3·41
= 135
123
− 82
123
=
135−82
123
= 53
123
19
7
+ 16
54
= 19
7
+ 8
27
= 19·27
7·27
+ 8·7
27·7
= 513
189
+
56
189
= 513+56
189
= 569
189
= 3 2
189
51
47
− 49
65
= 51
47
− 49
65
= 51·65
47·65
− 49·47
65·47
= 3315
3055
−
2303
3055
= 3315−2303
3055
= 1012
3055
38
82
+ 38
99
= 19
41
+ 38
99
= 19·99
41·99
+ 38·41
99·41
= 1881
4059
+
1558
4059
= 1881+1558
4059
= 3439
4059
56
33
− 30
32
= 56
33
− 15
16
= 56·16
33·16
− 15·33
16·33
= 896
528
−
495
528
= 896−495
528
= 401
528
96
80
+ 46
39
= 6
5
+ 46
39
= 6·39
5·39
+ 46·5
39·5
= 234
195
+ 230
195
=
234+230
195
= 464
195
= 2 74
195
49
79
− 29
82
= 49·82
79·82
− 29·79
82·79
= 4018
6478
− 2291
6478
=
4018−2291
6478
= 1727
6478
72
68
+ 46
99
= 18
17
+ 46
99
= 18·99
17·99
+ 46·17
99·17
= 1782
1683
+
782
1683
= 1782+782
1683
= 2564
1683
= 1 881
1683
42
49
− 38
59
= 6
7
− 38
59
= 6·59
7·59
− 38·7
59·7
= 354
413
− 266
413
=
354−266
413
= 88
413
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 36 / 41
Conclusion
Conclusion
lazy attributes allow designing a multi-stage initialization phase
benefit of common runtime (faster load) when using
◮ DBIx::Class
◮ Web::Simple (Jedi)
improve design by
◮ using roles for behavioral design (avoid duck typing)
◮ using explicit patterns for clear separation of concerns
◮ express intensions clearer for method overloading by using method modifiers
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 38 / 41
Resources Resources
Resources
Software
https://metacpan.org/pod/Moo/
https://github.com/moose/Moo
https://metacpan.org/search?q=MooX
https://metacpan.org/pod/MooX::Cmd
https://metacpan.org/pod/MooX::Options
https://metacpan.org/pod/MooX::ConfigFromFile
https://github.com/rehsack/App-Math-Tutor
IRC
irc://irc.perl.org/#moose
irc://irc.perl.org/#web-simple
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 39 / 41
Resources Thank you
Thank You For Contributing
Graham ”haarg” Knop Found a lot of spelling errors and first suggestions
Vincent ”celogeek” Bachelier Suggested some real examples
Fedor Babkin UML diagram improvements
Curtis ”Ovid” Poe Final review and figured out missing fundamentals
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 40 / 41
Resources Thank you
Thank You For Listening
Questions?
Jens Rehsack <rehsack@cpan.org>
Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 41 / 41

More Related Content

What's hot

What's hot (20)

All experiment of java
All experiment of javaAll experiment of java
All experiment of java
 
Class method
Class methodClass method
Class method
 
Advanced Python, Part 1
Advanced Python, Part 1Advanced Python, Part 1
Advanced Python, Part 1
 
Python: Migrating from Procedural to Object-Oriented Programming
Python: Migrating from Procedural to Object-Oriented ProgrammingPython: Migrating from Procedural to Object-Oriented Programming
Python: Migrating from Procedural to Object-Oriented Programming
 
C sharp chap5
C sharp chap5C sharp chap5
C sharp chap5
 
Python - OOP Programming
Python - OOP ProgrammingPython - OOP Programming
Python - OOP Programming
 
Methods
MethodsMethods
Methods
 
C sharp chap6
C sharp chap6C sharp chap6
C sharp chap6
 
Python programming- Part IV(Functions)
Python programming- Part IV(Functions)Python programming- Part IV(Functions)
Python programming- Part IV(Functions)
 
Functions and modules in python
Functions and modules in pythonFunctions and modules in python
Functions and modules in python
 
Java programming lab manual
Java programming lab manualJava programming lab manual
Java programming lab manual
 
Java programming lab_manual_by_rohit_jaiswar
Java programming lab_manual_by_rohit_jaiswarJava programming lab_manual_by_rohit_jaiswar
Java programming lab_manual_by_rohit_jaiswar
 
C sharp chap4
C sharp chap4C sharp chap4
C sharp chap4
 
Python Modules
Python ModulesPython Modules
Python Modules
 
Functional programming in Scala
Functional programming in ScalaFunctional programming in Scala
Functional programming in Scala
 
Python programming –part 7
Python programming –part 7Python programming –part 7
Python programming –part 7
 
Operator overloading
Operator overloadingOperator overloading
Operator overloading
 
Function overloading
Function overloadingFunction overloading
Function overloading
 
L03 Software Design
L03 Software DesignL03 Software Design
L03 Software Design
 
Python Modules
Python ModulesPython Modules
Python Modules
 

Similar to Moo at App::Math::Trainer

Moo at System::Image::Update
Moo at System::Image::UpdateMoo at System::Image::Update
Moo at System::Image::UpdateJens Rehsack
 
JLK Chapter 5 – Methods and ModularityDRAFT January 2015 Edition.docx
JLK Chapter 5 – Methods and ModularityDRAFT January 2015 Edition.docxJLK Chapter 5 – Methods and ModularityDRAFT January 2015 Edition.docx
JLK Chapter 5 – Methods and ModularityDRAFT January 2015 Edition.docxvrickens
 
Basic Oops concept of PHP
Basic Oops concept of PHPBasic Oops concept of PHP
Basic Oops concept of PHPRohan Sharma
 
OOP Is More Than Cars and Dogs
OOP Is More Than Cars and DogsOOP Is More Than Cars and Dogs
OOP Is More Than Cars and DogsChris Tankersley
 
Object Oriented Programming Short Notes for Preperation of Exams
Object Oriented Programming Short Notes for Preperation of ExamsObject Oriented Programming Short Notes for Preperation of Exams
Object Oriented Programming Short Notes for Preperation of ExamsMuhammadTalha436
 
Coming to Terms with OOP In Drupal - php[world] 2016
Coming to Terms with OOP In Drupal - php[world] 2016Coming to Terms with OOP In Drupal - php[world] 2016
Coming to Terms with OOP In Drupal - php[world] 2016Chris Tankersley
 
Functions2.pdf
Functions2.pdfFunctions2.pdf
Functions2.pdfprasnt1
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Fabien Potencier
 
EContent_11_2023_04_09_11_30_38_Unit_3_Objects_and_Classespptx__2023_03_20_12...
EContent_11_2023_04_09_11_30_38_Unit_3_Objects_and_Classespptx__2023_03_20_12...EContent_11_2023_04_09_11_30_38_Unit_3_Objects_and_Classespptx__2023_03_20_12...
EContent_11_2023_04_09_11_30_38_Unit_3_Objects_and_Classespptx__2023_03_20_12...vekariyakashyap
 
OOP Is More Then Cars and Dogs - Midwest PHP 2017
OOP Is More Then Cars and Dogs - Midwest PHP 2017OOP Is More Then Cars and Dogs - Midwest PHP 2017
OOP Is More Then Cars and Dogs - Midwest PHP 2017Chris Tankersley
 
Modules of the twenties
Modules of the twentiesModules of the twenties
Modules of the twentiesPuppet
 

Similar to Moo at App::Math::Trainer (20)

Moo at System::Image::Update
Moo at System::Image::UpdateMoo at System::Image::Update
Moo at System::Image::Update
 
Oops in php
Oops in phpOops in php
Oops in php
 
JLK Chapter 5 – Methods and ModularityDRAFT January 2015 Edition.docx
JLK Chapter 5 – Methods and ModularityDRAFT January 2015 Edition.docxJLK Chapter 5 – Methods and ModularityDRAFT January 2015 Edition.docx
JLK Chapter 5 – Methods and ModularityDRAFT January 2015 Edition.docx
 
Basic Oops concept of PHP
Basic Oops concept of PHPBasic Oops concept of PHP
Basic Oops concept of PHP
 
Introduction Php
Introduction PhpIntroduction Php
Introduction Php
 
Dutch PHP Conference 2013: Distilled
Dutch PHP Conference 2013: DistilledDutch PHP Conference 2013: Distilled
Dutch PHP Conference 2013: Distilled
 
OOP Is More Than Cars and Dogs
OOP Is More Than Cars and DogsOOP Is More Than Cars and Dogs
OOP Is More Than Cars and Dogs
 
Functions2.pptx
Functions2.pptxFunctions2.pptx
Functions2.pptx
 
Object Oriented Programming Short Notes for Preperation of Exams
Object Oriented Programming Short Notes for Preperation of ExamsObject Oriented Programming Short Notes for Preperation of Exams
Object Oriented Programming Short Notes for Preperation of Exams
 
Coming to Terms with OOP In Drupal - php[world] 2016
Coming to Terms with OOP In Drupal - php[world] 2016Coming to Terms with OOP In Drupal - php[world] 2016
Coming to Terms with OOP In Drupal - php[world] 2016
 
Functions2.pdf
Functions2.pdfFunctions2.pdf
Functions2.pdf
 
2 Functions2.pptx
2 Functions2.pptx2 Functions2.pptx
2 Functions2.pptx
 
Ch8(oop)
Ch8(oop)Ch8(oop)
Ch8(oop)
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3
 
Lecture 8.pdf
Lecture 8.pdfLecture 8.pdf
Lecture 8.pdf
 
Oops in PHP
Oops in PHPOops in PHP
Oops in PHP
 
EContent_11_2023_04_09_11_30_38_Unit_3_Objects_and_Classespptx__2023_03_20_12...
EContent_11_2023_04_09_11_30_38_Unit_3_Objects_and_Classespptx__2023_03_20_12...EContent_11_2023_04_09_11_30_38_Unit_3_Objects_and_Classespptx__2023_03_20_12...
EContent_11_2023_04_09_11_30_38_Unit_3_Objects_and_Classespptx__2023_03_20_12...
 
OOP Is More Then Cars and Dogs - Midwest PHP 2017
OOP Is More Then Cars and Dogs - Midwest PHP 2017OOP Is More Then Cars and Dogs - Midwest PHP 2017
OOP Is More Then Cars and Dogs - Midwest PHP 2017
 
java script
java scriptjava script
java script
 
Modules of the twenties
Modules of the twentiesModules of the twenties
Modules of the twenties
 

More from Jens Rehsack

Perl6 for-beginners
Perl6 for-beginnersPerl6 for-beginners
Perl6 for-beginnersJens Rehsack
 
A CMDB Driven by Perl
A CMDB Driven by PerlA CMDB Driven by Perl
A CMDB Driven by PerlJens Rehsack
 
PkgSrc in Five Minutes
PkgSrc in Five MinutesPkgSrc in Five Minutes
PkgSrc in Five MinutesJens Rehsack
 
Cross Compiling for Perl Hackers
Cross Compiling for Perl HackersCross Compiling for Perl Hackers
Cross Compiling for Perl HackersJens Rehsack
 
Perl on-embedded-devices
Perl on-embedded-devicesPerl on-embedded-devices
Perl on-embedded-devicesJens Rehsack
 

More from Jens Rehsack (6)

Perl6 for-beginners
Perl6 for-beginnersPerl6 for-beginners
Perl6 for-beginners
 
Unix::Statgrab
Unix::StatgrabUnix::Statgrab
Unix::Statgrab
 
A CMDB Driven by Perl
A CMDB Driven by PerlA CMDB Driven by Perl
A CMDB Driven by Perl
 
PkgSrc in Five Minutes
PkgSrc in Five MinutesPkgSrc in Five Minutes
PkgSrc in Five Minutes
 
Cross Compiling for Perl Hackers
Cross Compiling for Perl HackersCross Compiling for Perl Hackers
Cross Compiling for Perl Hackers
 
Perl on-embedded-devices
Perl on-embedded-devicesPerl on-embedded-devices
Perl on-embedded-devices
 

Recently uploaded

Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
Best Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfBest Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfIdiosysTechnologies1
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 

Recently uploaded (20)

Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Best Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfBest Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdf
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 

Moo at App::Math::Trainer

  • 1. Moo in practice - App::Math::Tutor Jens Rehsack Niederrhein Perl Mongers 2014-2015 Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 1 / 41
  • 2. Introduction Motivation Motivation Moo and App::Math::Tutor real world examples over far-fetched conceptuals MooX::Cmd, MooX::Options and MooX::ConfigFromFile provide way more features and flexibility than either ◮ App::Cmd with Getopt::Long::Descriptive ◮ MooseX::App::Cmd along with corresponding MooseX wrappers around related stuff 2nd generation of modern OO in Perl5 App::Math::Tutor Allow parents help their children improving their mathematical skills Add support for exercise types as children require provide extensible design to allow easy augment of exercise Goal: Improve to Web-Service, eg. by mapping MooX::Cmd to URI path and MooX::Options to GET parameters Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 3 / 41
  • 3. Introduction Audience Audience Audience Developers who want to create or improve Perl5 software Developers who want to learn how to develop modern OO with Perl5 Developers who are interested in developing mathematical exercises Prerequisites of the Audience Following knowledge is expected: General knowledge about object oriented programming or concepts like ◮ classes ◮ objects ◮ polymorphism, inheritance and/or roles ◮ methods, class functions ◮ attributes, properties slightly above basic Perl experience ever heard of Smalltalk and its OO-concept is a strong bonus Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 4 / 41
  • 4. Modules Classes and Roles Classes in Moo classes can be instantiated one can inherit from classes one can aggregate classes distinguish naming conflicts is up to developer { package Natural; use Moo; sub _stringify { ... }; } { package Roman; use Moo; extends "Natural"; sub _stringify { ... }; } my $natnum = Natural ->new( value => 42 ); say $natnum ->_stringify (); # 42 my $romnum = Roman ->new( value => 42 ); say $romnum ->_stringify (); # XLII Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 6 / 41
  • 5. Modules Classes and Roles Roles in Moo roles describe a dedicated behavior (e.g. printable) roles can be composed into classes one can’t inherit from roles - only consume roles cannot exist stand-alone roles are consumed once naming conflicts cause compile time error { package Printable; use Moo:: Role; # now it’s a role - no ’is a’ relationship anymore sub print { my $self = shift; say $self ->_stringify } } { package Natural; use Moo; # class with "Printable"; # consumes a role sub _stringify { ... }; } my $natnum = Natural ->new( value => 42 ); $natnum ->print; # 42 my $romnum = Roman ->new( value => 42 ); $romnum ->print; # XLII Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 7 / 41
  • 6. Attributes Attributes in Moo Attributes in Moo package VulFrac; use Moo; has nume rator => ( is => "ro", required => 1 ); has denom inator => ( is => "ro", required => 1 ); 1; use ”has” keyword to define a attribute attributes ”numerator” and ”denominator” attributes are immutable and required Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 8 / 41
  • 7. Attributes Attribute Options Attribute options - Selection I is mandatory behavior description ro defines the attribute is read-only rw defined the attribute is read/writable lazy defines the attribute is read-only with a lazy initialization, implies builder => 1 required when set to a true value, attribute must be passed on instantiation init arg Takes the name of the key to look for at instantiation time of the object. A common use of this is to make an underscored attribute have a non-underscored initialization name. undef means that passing the value in on instantiation is ignored. isa defines a subroutine (coderef) which is called to validate values to set coerce defines a subroutine (coderef) which forces attribute values default subroutine (coderef) which is called to initialize an attribute Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 9 / 41
  • 8. Attributes Attribute Options Attribute options - Selection II Following options can benefit from attribute shortcuts: the value of 1 instead of a method name means to generate a coderef which calls the method ${option name} ${attr name} builder takes a method name (string) which is called to initialize an attribute (calls build ${attr name} on attribute shortcut) trigger takes a subroutine (coderef) which is called anytime the attribute is set (calls trigger ${attr name} on attribute shortcut) clearer takes a method name (string) which will clear the attribute (provides clear ${attr name} on attribute shortcut) predicate takes a method name (string) which will return true if an attribute has a value (provides has ${attr name} on attribute shortcut) Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 10 / 41
  • 9. Methods Method Examples Methods in Moo I package VulFrac; use Moo; use overload ’""’ => " _stringify", ’0+’ => "_numify", ’bool ’ => sub { 1 }, ’<=>’ => " _num_compare"; has numerator => ( is => "ro", required => 1 ); has denominator => ( is => "ro", required => 1, isa => sub { $_ [0] != 0 or die "Not != 0" }; sub _stringify { my $self = shift; return sprintf(" frac {%s}{%s}", $self ->numerator , $self -> denominator ); } sub _numify { $_[0]-> numerator / $_[0]-> denominator ; } ... Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 11 / 41
  • 10. Methods Method Examples Methods in Moo II package Rationale; use Moo; extends "VulFrac"; has digits => ( is => "ro", required => 1 ); sub _stringify { my $digits = $_[0]-> digits; sprintf("%.${digits}g", $_[0]-> _numify ); } nothing like MooseX::Declare - pure Perl5 keywords are enough for plain methods Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 12 / 41
  • 11. Methods Method Modifiers Method Modifiers Method modifiers are a convenient feature from the CLOS (Common Lisp Object System) world: before before method(s) => sub { ...} before is called before the method it is modifying. Its return value is totally ignored. after after method(s) => sub { ...} after is called after the method it is modifying. Its return value is totally ignored. around around method(s) => sub { ...} around is called instead of the method it is modifying. The method you’re overriding is passed as coderef in the first argument. - No support for super, override, inner or augment In doubt MooX::Override provides override and super while MooX::Augment provides augment and inner Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 13 / 41
  • 12. Methods Method Modifiers Method Modifiers - Advantages supersedes $self->SUPER::foo(@ ) syntax cleaner interface than SUPER allows multiple modifiers in single namespace also possible from within roles and not restricted to inheritance ensures that inherited methods invocation happens right (mostly - remember around) no need to change packages Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 14 / 41
  • 13. Methods Method Modifiers Methods Modifiers - around avoid calling $orig package App:: Math :: Tutor :: Role :: Roman; use Moo:: Role; with "App:: Math :: Tutor :: Role :: Natural"; { package RomanNum; use Moo; extends "NatNum"; # derives overloading ! sub _stringify { ... } } around " _guess_natural_number" => sub { my $orig = shift; my $max_val = $_[0]-> format; my $value = int( rand( $max_val - 1 ) ) + 1; return RomanNum ->new( value => $value ); }; captures control receives responsibility runtime of modified method completely eliminated Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 15 / 41
  • 14. Methods Method Modifiers Methods Modifiers - around modifying $orig return value package App:: Math :: Tutor :: Role :: Roman; use Moo:: Role; with "App:: Math :: Tutor :: Role :: Natural"; { package RomanNum; use Moo; extends "NatNum"; # derives overloading ! sub _stringify { ... } } around " _guess_natural_number" => sub { my $orig = shift; my $num = $orig ->(@_); return RomanNum ->new( value => $num ->value ); }; modifies only required part leaves most responsibility in modified method runtime of modified method added to this method’s runtime Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 16 / 41
  • 15. Structure Frontend Frontend (dictated by MooX::Cmd) App::Math::Tutor App::Math::Tutor::Cmd::VulFrac App::Math::Tutor::Cmd::VulFrac::Cmd::Add App::Math::Tutor::Cmd::VulFrac::Cmd::Mul App::Math::Tutor::Cmd::VulFrac::Cmd::Cast App::Math::Tutor::Cmd::Natural App::Math::Tutor::Cmd::Natural::Cmd::Add App::Math::Tutor::Cmd::Natural::Cmd::Mul App::Math::Tutor::Cmd::Roman App::Math::Tutor::Cmd::Roman::Cmd::Add App::Math::Tutor::Cmd::Roman::Cmd::Cast App::Math::Tutor::Cmd::Unit App::Math::Tutor::Cmd::Unit::Cmd::Add App::Math::Tutor::Cmd::Unit::Cmd::Mul App::Math::Tutor::Cmd::Unit::Cmd::Cast Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 18 / 41
  • 16. Structure CLI Concept Exercise Groups App::Math::Tutor::Cmd::VulFrac Exercises in vulgar fraction calculation App::Math::Tutor::Cmd::Natural Exercises in calculations using natural numbers App::Math::Tutor::Cmd::Roman Exercises in calculations using natural numbers, but show them using roman number encoding (exercises and solutions) App::Math::Tutor::Cmd::Unit Exercises in calculations using units (times, currency, . . . ) App::Math::Tutor::Cmd::Power Exercises in calculations of power mathematics App::Math::Tutor::Cmd::Polynom Exercises for polynomial mathematics (Zero of a function, Vertex, . . . ) Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 19 / 41
  • 17. Design Simple Exercise Typical Exercise design App::Math::Tutor::Cmd::VulFrac::Cmd::Add build exercise() : exercise App::Math::Tutor::Role::VulFracExercise format App::Math::Tutor::Role::VulFrac check vulgar fraction() : bool guess vulgar fraction() : VulFrac get vulgar fractions() : [ VulFrac ] VulFrac num denum stringify() : Str numify() : Num num compare() : Int euklid() : Int gcd() : Int reduce() : VulFrac reciprocal() : VulFrac App::Math::Tutor::Role::Exercise exercise : lazy # { section, caption, label, # header, challenges, solutions } output name : lazy template filename : lazy build exercise() = 0 : exercise build output name() : Str build template filename() = 0 : Str execute() Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 20 / 41
  • 18. Design Derived Exercise Derived Exercise design App::Math::Tutor::Cmd::Roman::Cmd::Add build exercise() : exercise App::Math::Tutor::Role::NaturalExercise format App::Math::Tutor::Role::Roman around => guess natural number() : Roman App::Math::Tutor::Role::Natural check natural number() : bool guess natural number() : Natural get natural number() : [ Natural ] RomanNum stringify() : Str Natural value stringify() : Str numify() : Num num compare() : Int App::Math::Tutor::Role::Exercise exercise : lazy # { section, caption, label, # header, challenges, solutions } output name : lazy template filename : lazy build exercise() = 0 : exercise build output name() : Str build template filename() = 0 : Str execute() Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 21 / 41
  • 19. Improvements Design Improving design introduce factories add lazy factory attribute (allowes overriding factory to use by around’ing builder) separate number classes (type system, but no MooseX::Types) approval for reasonable exercise value should be part of factory approval for valid number should be coerced (trigger?) Design history I started with just vulgar fraction exercises Design covered exactly those needs Design future Modern Perl-OO allowes easy refactoring to apply above improvements Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 22 / 41
  • 20. MooX General purpose eXtensions MooX in general Some Moo extensions for getting a picture - the list is neither complete nor is it intended to be MooX Distributions MooX::Log::Any logging role building a very lightweight wrapper to Log::Any MooX::Validate minimalist Data Validation for Moo MooX::Types::MooseLike Moose like types for Moo MooX::Override adds ”override method => sub . . . ” support to Moo MooX::Augment adds ”augment method => sub . . . ” support to Moo MooX::late easily translate Moose code to Moo MooX::PrivateAttributes create attribute only usable inside your package MooX::Singleton turn your Moo class into singleton MooX::Aliases easy aliasing of methods and attributes in Moo Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 24 / 41
  • 21. MooX CLI related eXtensions MooX Distributions for CLI MooX::Cmd giving an easy Moo style way to make command organized CLI apps support sub-commands with separated options when used together with MooX::Options MooX::Options explicit Options eXtension for Object Class no mess with composed attributes MooX::ConfigFromFile Moo eXtension for initializing objects from config file RC files with structures (JSON, INI, YAML, XML, ...) Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 25 / 41
  • 22. MooX CLI related eXtensions General CLI Construction Flow :main :MooX::Cmd :MooX::Options :MooX::ConfigFromFile :Moo new with cmd() buildcommand commands() splitargv new with options() parse options new() BUILDARGS() super->BUILDARGS() buildloaded config helpon exception execute Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 26 / 41
  • 23. Provided Framework Exercise Role package App:: Math :: Tutor :: Role :: Exercise; use strictures; # instead of strict + warnings use Moo:: Role; use MooX :: Options; option quantity => ( is => "ro", doc => "Specifies number of exercises to generate", long_doc => "Specify number of exercises to generate. " . "In case of several kind of ...", format => "i", short => "n", default => sub { 15 }, ); has output _name => ( is => "lazy" ); sub _build_output_name { join( "", map { $_ -> command_name || "" } @{ $_[0]-> command_chain } ); } being a role (no ”is a” relationship) and add CLI options capabilities defining an attribute which will be initialized by command line support MooX::Option’s --man usage feature attribute for output file to generate — lazy to allow provide individual name builder Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 28 / 41
  • 24. Provided Framework Exercise Role has exercises => ( is => "lazy" ); sub execute { my $exercises = $_[0]->exercises; my $ttcpath = File ::Spec ->catfile( File :: ShareDir :: dist_dir("App -Math -Tutor"), $_[0]-> template_filename . ".tt2" ); my $template = Template ->new( { ABSOLUTE => 1 }); my $rc = $template ->process( $ttcpath , { exercises => $exercises , output => { format => ’pdf’ }, }, $_[0]-> output_name . ’.pdf’); $rc or croak( $template ->error () ); return 0; } attribute containing the exercises definitions, exercises itself and their solutions (depending on template) — lazy implies requires ’’ build exercises’’ method to satisfy MooX::Cmd fetch exercises definition implies calling build exercises build full qualified path of template file name residing in app’s share directory, instantiate template processor and run it force output format ”pdf” (Template::LaTeX will be instructed by template) Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 29 / 41
  • 25. Provided Framework Vulgar Fraction Exercise Role package App:: Math :: Tutor :: Role ::Vul FracExercise; use strictures; use Moo:: Role; use MooX :: Options; with "App:: Math :: Tutor :: Role :: Exercise", "App:: Math :: Tutor :: Role :: VulFrac"; option format => ( is => "ro", doc => "specifies format of numerator/ denominator ", long_doc => "Allow specifying the format of the numerator/ denominator ...", isa => sub { defined( $_[0] ) and !ref $_[0] and $_ [0] !~ m ,^d?n+(?:/d?n+)?$, and die("Invalid format"); }, coerce => sub { ... my ( $fmta , $fmtb ) = ( $_[0] =~ m ,^(d?n+)(?:/(d?n+))?$, ); $fmtb //= $fmta; my $starta = "1"; my $startb = "1"; $fmta =~ s/^(d)(.*)/ $2/ and $starta = $1; $fmtb =~ s/^(d)(.*)/ $2/ and $startb = $1; [ $starta . "0" x length($fmta), $startb . "0" x length($fmtb) ] }, default => sub { return [ 100, 100 ]; }, format => "s", ); be a nice package ˆWrole, intending to provide command line options for instantiation compose role behavior using Exercise and VulFrac define option coercing option string into array ensuring the array ref as value Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 30 / 41
  • 26. Create Exercise Preamble package App:: Math :: Tutor :: Cmd:: VulFrac ::Cmd :: Add; use strictures; use Moo; use MooX :: Cmd; use MooX :: Options; has template_filename => ( is => "ro", default => "twocols"); with "App:: Math :: Tutor :: Role :: VulFracExercise "; $ mtut vulfrac add we’re of course a nice class satisfy requirement of Exercise role: provide template filename – two column template (for addition and substraction) compose role ...VulFracExercise Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 31 / 41
  • 27. Create Exercise Create Exercise Numbers sub _build_exercises { my ($self) = @_; my (@tasks ); foreach my $i ( 1 .. $self ->amount ) { my @line; for ( 0 .. 1 ) { # 0: +, 1: - my ( $a , $b ) = $self -> get_vulgar_fractions (2); push @line , [ $a , $b ]; } push @tasks , @line; } my $exercises = ...; return $exercises; } exercise builder has to be provided by individual exercise hold tasks of the exercise sheet how many tasks per sheet? (remember the option in ...Role::Exercise) a ”+” and a ”-” exercise per line invoke factory per task safe each line for processing Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 32 / 41
  • 28. Create Exercise Format Challenge / Solution my $exercises = { section => "Vulgar fraction addition / subtraction ", caption => ’Fractions ’, label => ’vulgar_fractions_addition ’, header => [ [ ’Vulgar Fraction Addition ’, ’Vulgar Fraction Su challenges => [], solutions => [], }; foreach my $line (@tasks) { my ( @solution , @challenge ); foreach my $i ( 0 .. 1 ) { my ( $a , $b , @way ) = @{ $line ->[$i] }; my $op = $i ? ’-’ : ’+’; $op eq ’-’ and $a < $b and ( $b , $a ) = ( $a , $b ); push @challenge , sprintf( ’$ %s %s %s = $’, $a , $op , $b ); push @way , sprintf( ’%s %s %s’, $a , $op , $b ); ... } push( @{ $exercises ->{ challenges} }, @challenge ); push( @{ $exercises ->{ solutions} }, @solution ); } create exercise structure containing challenges and solutions loop over created tasks and exercises per line format challenge using operator ’""’ of VulFrac objects same (but different) opening ”way” and remember the little thingies . . . Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 33 / 41
  • 29. Create Exercise Format Solutions sub _build_exercises { ( $a , $b ) = ( $a ->_reduce , $b = $b ->_reduce ); push @way , sprintf( ’%s %s %s’, $a , $op , $b ) if ( $a ->num != $line ->[$i]->[0]->num or $b ->num != ... ); my $gcd = VulFrac ->new( num => $a ->denum , denum => $b ->denum )->_gcd; my ( $fa , $fb ) = ( $b ->{ denum} / $gcd , $a ->{ denum} / $gcd ); push @way , sprintf( ’frac {%d cdot %d}{%d cdot %d} %s ...’, $a ->num , $fa , $a ->denum , $fa , $op , $b ->num , $fb , ... ); push @way , sprintf( ’frac {%d}{%d} %s frac {%d}{%d}’, $a ->num*$fa , $a ->denum*$fa , $op , $b ->num*$fb , $b ->denum*$fb ); push @way , sprintf( ’frac {%d %s %d}{%d}’, $a ->num * $fa , $op , $b ->num * $fb , $a ->denum * $fa ); my $s = VulFrac ->new( denum => $a ->denum * $fa , num => $i ? $a ->num * $fa - $b ->num * $fb : ...s/ -/+/); push @way , "" . $s; my $c = $s ->_reduce; $c ->num != $s ->num and push @way , " $c ->num > $c ->denum and $c ->denum > 1 and push @way , $c ->_stringify(1); push( @solution , ’$ ’ . join( " = ", @way ) . ’ $’ ); } try to reduce operands and add them to opening when successful World of Handcraft: show calculation method by determine geatest common divisor of operands denominator, format subsequent steps to reach the solution remark possible reducing, mixed fraction, cord it and go ahead Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 34 / 41
  • 30. Created Exercise Output Challenges Vulgar Fraction Addition Vulgar Fraction Subtraction 99 67 + 43 84 = 45 41 − 32 48 = 19 7 + 16 54 = 51 47 − 49 65 = 38 82 + 38 99 = 56 33 − 30 32 = 96 80 + 46 39 = 49 79 − 29 82 = 72 68 + 46 99 = 42 49 − 38 59 = Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 35 / 41
  • 31. Created Exercise Output Solutions Vulgar Fraction Addition Vulgar Fraction Subtraction 99 67 + 43 84 = 99·84 67·84 + 43·67 84·67 = 8316 5628 + 2881 5628 = 8316+2881 5628 = 11197 5628 = 15569 5628 45 41 − 32 48 = 45 41 − 2 3 = 45·3 41·3 − 2·41 3·41 = 135 123 − 82 123 = 135−82 123 = 53 123 19 7 + 16 54 = 19 7 + 8 27 = 19·27 7·27 + 8·7 27·7 = 513 189 + 56 189 = 513+56 189 = 569 189 = 3 2 189 51 47 − 49 65 = 51 47 − 49 65 = 51·65 47·65 − 49·47 65·47 = 3315 3055 − 2303 3055 = 3315−2303 3055 = 1012 3055 38 82 + 38 99 = 19 41 + 38 99 = 19·99 41·99 + 38·41 99·41 = 1881 4059 + 1558 4059 = 1881+1558 4059 = 3439 4059 56 33 − 30 32 = 56 33 − 15 16 = 56·16 33·16 − 15·33 16·33 = 896 528 − 495 528 = 896−495 528 = 401 528 96 80 + 46 39 = 6 5 + 46 39 = 6·39 5·39 + 46·5 39·5 = 234 195 + 230 195 = 234+230 195 = 464 195 = 2 74 195 49 79 − 29 82 = 49·82 79·82 − 29·79 82·79 = 4018 6478 − 2291 6478 = 4018−2291 6478 = 1727 6478 72 68 + 46 99 = 18 17 + 46 99 = 18·99 17·99 + 46·17 99·17 = 1782 1683 + 782 1683 = 1782+782 1683 = 2564 1683 = 1 881 1683 42 49 − 38 59 = 6 7 − 38 59 = 6·59 7·59 − 38·7 59·7 = 354 413 − 266 413 = 354−266 413 = 88 413 Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 36 / 41
  • 32. Conclusion Conclusion lazy attributes allow designing a multi-stage initialization phase benefit of common runtime (faster load) when using ◮ DBIx::Class ◮ Web::Simple (Jedi) improve design by ◮ using roles for behavioral design (avoid duck typing) ◮ using explicit patterns for clear separation of concerns ◮ express intensions clearer for method overloading by using method modifiers Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 38 / 41
  • 34. Resources Thank you Thank You For Contributing Graham ”haarg” Knop Found a lot of spelling errors and first suggestions Vincent ”celogeek” Bachelier Suggested some real examples Fedor Babkin UML diagram improvements Curtis ”Ovid” Poe Final review and figured out missing fundamentals Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 40 / 41
  • 35. Resources Thank you Thank You For Listening Questions? Jens Rehsack <rehsack@cpan.org> Jens Rehsack (Niederrhein.PM) Moo in practice - App::Math::Tutor 2014-2015 41 / 41