SlideShare une entreprise Scribd logo
1  sur  53
Télécharger pour lire hors ligne
DON’T RTFM - WTFM
Write the F--king Fantastic Manual
Or how I learned to stop
worrying and love the code
or...
Newbies write the best docs.
I will teach you how to be a newbie all over again!
My background
Like most perl programmers I’m self taught
But I learned very slowly since 1999
Why?
Programming is 10% of my job and voluntary.
Documentation assumes too much pre-existing knowledge
My background - cont
Teaching Statistics for science and business students
They hate statistics, Why?
How can I make them hate statistics less?
The problem of contrived examples.
Our goal is to prime them to deal with real world problems in the
future.
How did I solve this problem?
Catalyst
Catalyst::Manual::Tutorial
didn’t work
12:23 <@kd> purl, doesn't work?
12:23 < purl> Look buddy, doesn't work is a strong statement. Does it
sit on the couch all day? Is it making faces at you? Does it want more
money? Is it sleeping with your girlfriend? Please be specific!
Fixed in Catalyst 5.65: 21st Feb 2006 :13 months since the
beginning of the project!
Remove irrelevant information:
created "MyApp"
created "MyApp/script"
- created "MyApp/lib"
- created "MyApp/root"
- created "MyApp/root/static"
- created "MyApp/root/static/images"
- created "MyApp/t"
- created "MyApp/t/Model"
- created "MyApp/t/View"
- created "MyApp/t/Controller"
- created "MyApp/lib/MyApp"
- created "MyApp/lib/MyApp/Model"
- created "MyApp/lib/MyApp/View"
- created "MyApp/lib/MyApp/Controller"
- created "MyApp/lib/MyApp.pm"
- created "MyApp/Build.PL"
- created "MyApp/Makefile.PL"
- created "MyApp/README"
- created "MyApp/Changes"
- created "MyApp/t/01app.t"
- created "MyApp/t/02pod.t"
- created "MyApp/t/03podcoverage.t"
- created "MyApp/root/static/images/catalyst_logo.png"
- created "MyApp/root/static/images/btn_120x50_built.png"
- created "MyApp/root/static/images/btn_120x50_built_shadow.png"
- created "MyApp/root/static/images/btn_120x50_powered.png"
- created "MyApp/root/static/images/btn_120x50_powered_shadow.png"
- created "MyApp/root/static/images/btn_88x31_built.png"
- created "MyApp/root/static/images/btn_88x31_built_shadow.png"
- created "MyApp/root/static/images/btn_88x31_powered.png"
- created "MyApp/root/static/images/btn_88x31_powered_shadow.png"
- created "MyApp/root/favicon.ico"
- created "MyApp/script/myapp_cgi.pl"
- created "MyApp/script/myapp_fastcgi.pl"
- created "MyApp/script/myapp_server.pl"
- created "MyApp/script/myapp_test.pl"
+ ... output snipped
created "MyApp/script/myapp_create.pl"
Make the supplied code work:
- sub greet : Local
- {
- my ($self, $context) = @_;
+ sub greet : Local {
+ my ($self, $c) = @_;
- my $name = $context->req->params->{name};
- $context->log->debug("Got name: $namen");
+ my $name = $c->req->param('name');
+ $c->log->debug("Got name: $namen");
- if(!$name)
- {
- $context->stash->{message} = 'Please fill in a name!';
+ if ($c->req->method eq 'POST') {
+ if(!$name) {
+ $c->stash->{message} = 'Please fill in a name!';
+ }
+ else {
+ $c->stash->{message} = "Hello $name!";
}
- else
- {
- $context->stash->{message} = "Hello $name!";
}
- $context->stash->{template} = 'greet.tt';
+ $c->stash->{template} = 'greet.tt';
}
Show that the code works
Always provide a reference implementation:
The first fully working Catalyst Tutorial:
http://dev.catalystframework.org/old-wiki/attachment/wiki/WikiStart/tutorial.tar.gz
This set up the future of Catalyst
Catalyst code is working code
Catalyst educational material is always accompanied by
working code.
The original Catalyst tutorial lasted 9 months
Kennedy Clark turned up and wrote a big tutorial
A real published author :)
(we have a history of these in Catalyst)
On to the future
The new tutorial
lib/Catalyst/Manual/Tutorial.pod
lib/Catalyst/Manual/Tutorial/Intro.pod
lib/Catalyst/Manual/Tutorial/CatalystBasics.pod
lib/Catalyst/Manual/Tutorial/BasicCRUD.pod
lib/Catalyst/Manual/Tutorial/Authentication.pod
lib/Catalyst/Manual/Tutorial/Authorization.pod
lib/Catalyst/Manual/Tutorial/AdvancedCRUD.pod
lib/Catalyst/Manual/Tutorial/Testing.pod
lib/Catalyst/Manual/Tutorial/Debugging.pod
lib/Catalyst/Manual/Tutorial/Appendices.pod
Always give examples
You can obtain the code for all the tutorial examples from the
catalyst subversion repository by issuing the command:
svn co http://dev.catalyst.perl.org/repos/Catalyst/tags/
examples/Tutorial/MyApp/5.7/ CatalystTutorial
This will download the current code for each tutorial chapter in
the CatalystTutorial directory. Each example application
directory has the same name as the tutorial chapter.
Reduce the barrier to entry
Sometimes OSS programmers can seem hostile.
Aim to only have to answer the same question once.
Write the answer down
In the pod
In the wiki
Teach the bot
My most useful factoid
04:45 <@kd> purl, make_schema_at?
04:45 <+purl> make_schema_at is what i want
04:47 <@kd> no purl, make_schema_at is perl -
MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:.
/lib -e 'make_schema_at("My::Schema", { debug => 1,
db_schema => "myschemaname", components =>
["InflateColumn::DateTime"] },
["dbi:Pg:host=localhost;dbname=mydbname", "user",
"pass" ])'
04:47 <+purl> okay, kd.
Summary:
Always always always provide a working example.
Use your tests as a basis if you want.
Point the users to the tests in the pod if necessary.
Why?
To avoid constantly being asked stupid questions.
If you don’t, what happens?
Nobody cares because nobody uses your code.
or: You’re constantly asked stupid questions
or: If you’re lucky, someone like me comes along, asks the stupid
questions, and writes the answers down.
The third option doesn’t happen often.
Cognitive Load Theory
An educational technique used in school Maths and Science
Education.
KISS - Keep It Simple Stupid
Working memory has a finite capacity:
7±2 items
We should aim to ensure that only relevant items are presented
to the reader, so their memory capacity isn’t overloaded.
The Parts of Cognitive Load
Intrinsic (internal) cognitive load:
Task relevant demands
e.g. Programming logic
Extrinsic cognitive load:
Business logic
Prerequisite knowledge
The components of software
Programming logic
Task logic
Business logic
Business logic can be big, complex and poorly defined.
Add a dash of chaos theory
e.g. a three parameter model with a
single outcome variable can result in
substantial divergence after a single
change in initial conditions.
It only needs 3 parameters to create chaos.
Business logic always has > 3 parameters
How to minimise chaos
Make examples artificial and contrived.
How do we do this without being boring and pointless?
Case study. Catalyst Book
LolCatalyst
Translate snippets of text to LolCat.
CPAN module: Acme::LOLCAT
Educational purpose
Show how to display a web page
Show how to create a web service
Show that authentication is possible
Catalyst::Helper::AuthDBIC
(or what I spent my time on when I visited Shadowcat to
plan the book)
Assumed knowledge
Basic HTTP
GET v POST requests
Basic Perl data structures
What’s an editor and how do I use it?
How do I run a perl script?
How do I install CPAN modules.
Assumed knowledge cont.
If the reader doesn’t possess the assumed knowledge the
extrinsic and intrinsic cognitive load are both high.
Authentication
Authentication is complicated
Instead of explaining it, I wrote a Catalyst::Helper that modifies
an existing application
Thank you PPI :)
Problem solved in a single page of text.
Web service
Catalyst web services are simple
In LolCatalyst/Controller/Root:
sub translate_service : Local {
my ($self, $c) = @_;
$c->forward('translate');
$c->stash->{current_view} = 'Service';
}
In LolCatalyst/View/Service:
package LolCatalyst::View::Service;
use strict;
use base 'Catalyst::View::JSON';
__PACKAGE__->config({ expose_stash => [ qw/lol result/ ] });
1;
So far so good.
No business logic
Some programming logic
Basic introduction to some core catalyst concepts
A Controller with minimal
business logic
sub default :Path {
my ( $self, $c ) = @_;
$c->response->status(404);
$c->response->body( 'Page not found' );
}
sub translate :Local {
my ($self, $c) = @_;
my $lol = $c->req->body_params->{lol}; # only for a POST request
# $c->req->params->{lol} would catch GET or POST
# $c->req->query_params would catch GET params only
$c->stash(
lol => $lol,
result => $c->model('Translate')->translate($lol),
template => 'index.tt',
);
}
Assumed knowledge
New knowledge
Total number of concepts
added
View
Service
Dispatch
We still have room for 4±2
Template View (almost
identical to Service view)
Model:
package LolCatalyst::Lite::Model::Translate;
use strict;
use warnings;
use parent 'Catalyst::Model';
use Acme::LOLCAT ();
use Memoize;
memoize ('translate');
sub translate {
my ($self, $text) = @_;
return Acme::LOLCAT::translate($text);
}
1;
Error trapping (in
Controller::Root):
sub end :ActionClass('RenderView') {
my ($self, $c) = @_;
my $errors = scalar @{$c->error};
if ($errors) {
$c->res->status(500);
$c->res->body('internal server error');
$c->clear_errors;
}
}
Assumed knowledge
Not very different from “normal” programing!
The final result
A very simple application
Minimal extra learning
required to understand the
model
Minimal programming logic
features.
What next?
Get mst to refactor
Let’s make a generic translation application.
Many more moving parts.
Large conceptual territory to cover
How do we make sure that we only present relevant information
to the reader?
Git based education.
Git - the other meaning
Urbandictionary.com:
A completely ignorant, childish person with no manners
Total and utter tosser who is incapable of doing anything
other than annoying people, and not in a way that is funny to
others
Means idiot or rotter. Often used affectionately like bugger,
but when used seriously is probably more potent (but less
rude) than the worst swear words.
Git as an educational resource:
the approach
Each commit introduces a single new idea to the reader
Advantages:
Clarity
Disadvantages:
Labour intensive
Need to rewrite history - story telling rather than “real” development
But we can count the number of concepts introduced easily by looking at
the diffs.
Extending LolCatalyst
review git history
number of concepts per commit
shows how clearly we have explained the problem
Case study - Moose Cookbook
The Moose cookbook is generally excellent and comprehensive.
but ...
The early examples are simple, but the become more complex
quickly
Where’s the code?
Reducing complexity
Reduce business logic
reduce extrinsic cognitive load
Simplify programming logic
a delicate balance between being meaningful and too
contrived
package Point;
package Point;
use Moose;
has 'x' => (isa => 'Int', is => 'rw', required => 1);
has 'y' => (isa => 'Int', is => 'rw', required => 1);
sub clear {
my $self = shift;
$self->x(0);
$self->y(0);
}
package Point3D;
package Point3D;
use Moose;
extends 'Point';
has 'z' => (isa => 'Int', is => 'rw', required => 1);
after 'clear' => sub {
my $self = shift;
$self->z(0);
};
Where is the code - hidden in
the pod=begin testing
my $point = Point->new( x => 1, y => 2 );
isa_ok( $point, 'Point' );
isa_ok( $point, 'Moose::Object' );
is( $point->x, 1, '... got the right value for x' );
is( $point->y, 2, '... got the right value for y' );
$point->y(10);
is( $point->y, 10, '... got the right (changed) value for y' );
dies_ok {
$point->y('Foo');
}
'... cannot assign a non-Int to y';
dies_ok {
Point->new();
}
'... must provide required attributes to new';
$point->clear();
is( $point->x, 0, '... got the right (cleared) value for x' );
is( $point->y, 0, '... got the right (cleared) value for y' );
# check the type constraints on the constructor
### the remaining test code is not relevant to the example
### and should be elsewhere!!!
ALWAYS
ADVERTISE YOUR EXAMPLES
Unadvertised examples are extra extrinsic congnitive load
ASSUME I WILL NEVER READ
YOUR SOURCE CODE
TIME TO WORK
Contributors should get a copy of:
http://github.com/singingfish/German-Perl-Documentation-Workshop
or
http://xrl.us/bhn6xm
Task 1: Moose+DBIC
Lots of interest in how to integrate Moose with DBIC
No example driven documentation on how to do this
No example driven documentation on why you want this
Good starting material:
DBIx::Class::Manual::Example
http://localhost:2963/~frew/DBIx-Class-0.08122/
DBIx-Class-0.08122/lib/DBIx/Class/Manual/
Task 2: Better explanation of
Moose Roles
Moose Roles
The existing Cookbook Examples have too much business
logic.
There are inline test examples, but unadvertised
http://localhost:2963/~flora/Moose-1.06/Moose-1.06/
lib/Moose/Cookbook/Roles/Recipe1.pod
Task 3: Coercion
Too confusing. Too much cognitive load
Too many ways to do it?
Show the simplest way
Show a more flexible way
Minimise business logic
http://localhost:2963/~flora/Moose-1.06/Moose-1.06/lib/
Moose/Cookbook/Basics/Recipe5.pod
Task 4: Better explanation of
metaprogramming
Why metaprogramming?
Why make_immutable
Why not make_immutable
Where’s the simple example working code?
http://localhost:2963/~flora/Moose-1.06/Moose-1.06/lib/
Moose/Cookbook/Meta/Recipe1.pod
But ...
I can’t write well
I don’t speak good enough English.
Catalyst Process:
someone writes docs.
kd reviews docs for content (major edits)
the_jester reviews docs for grammar and spelling (minor
edits)
Your writing and language skills don’t matter because
someone else will fix the problems
Task 5: Moose::Manual::Index
Let’s crowdsource!
Read a moose perldoc page.
Write down the names of the important concepts
If you want write an explanation
If you can’t work this out, just write the name of the concept
Write a short explanation of the concept.
Pod format
Everyone read a Moose man page
Each time you see a new concept, write it down:
=head2 CONCEPT
name of concept
=head3 EXPLANATION
what it does here
=head3 MENTIONS
where it’s mentioned elsewhere in the docs
Patches welcome
To the github repository
Or patches/files to diment@gmail.com

Contenu connexe

Tendances

Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceJesse Vincent
 
Best Practices for Front-End Django Developers
Best Practices for Front-End Django DevelopersBest Practices for Front-End Django Developers
Best Practices for Front-End Django DevelopersChristine Cheung
 
Joomla security nuggets
Joomla security nuggetsJoomla security nuggets
Joomla security nuggetsguestbd1cdca
 
Writing your Third Plugin
Writing your Third PluginWriting your Third Plugin
Writing your Third PluginJustin Ryan
 
Introduction To Django
Introduction To DjangoIntroduction To Django
Introduction To DjangoJay Graves
 
Django for Beginners
Django for BeginnersDjango for Beginners
Django for BeginnersJason Davies
 
Turbogears Presentation
Turbogears PresentationTurbogears Presentation
Turbogears Presentationdidip
 
Behat - Drupal South 2018
Behat  - Drupal South 2018Behat  - Drupal South 2018
Behat - Drupal South 2018Berend de Boer
 
How does get template part works in twenty ten theme
How does get template part works in twenty ten themeHow does get template part works in twenty ten theme
How does get template part works in twenty ten thememohd rozani abd ghani
 
RSpec User Stories
RSpec User StoriesRSpec User Stories
RSpec User Storiesrahoulb
 
Create a web-app with Cgi Appplication
Create a web-app with Cgi AppplicationCreate a web-app with Cgi Appplication
Create a web-app with Cgi Appplicationolegmmiller
 
Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Jalpesh Vasa
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016CiaranMcNulty
 
Django Interview Questions and Answers
Django Interview Questions and AnswersDjango Interview Questions and Answers
Django Interview Questions and AnswersPython Devloper
 
Story Driven Development With Cucumber
Story Driven Development With CucumberStory Driven Development With Cucumber
Story Driven Development With CucumberSean Cribbs
 
Introduction To Lamp
Introduction To LampIntroduction To Lamp
Introduction To LampAmzad Hossain
 
Drupal 8: Huge wins, a Bigger Community, and why you (and I) will Love it
Drupal 8: Huge wins, a Bigger Community, and why you (and I) will Love itDrupal 8: Huge wins, a Bigger Community, and why you (and I) will Love it
Drupal 8: Huge wins, a Bigger Community, and why you (and I) will Love itRyan Weaver
 

Tendances (20)

Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
 
Best Practices for Front-End Django Developers
Best Practices for Front-End Django DevelopersBest Practices for Front-End Django Developers
Best Practices for Front-End Django Developers
 
BDD, Behat & Drupal
BDD, Behat & DrupalBDD, Behat & Drupal
BDD, Behat & Drupal
 
Joomla security nuggets
Joomla security nuggetsJoomla security nuggets
Joomla security nuggets
 
Writing your Third Plugin
Writing your Third PluginWriting your Third Plugin
Writing your Third Plugin
 
Introduction To Django
Introduction To DjangoIntroduction To Django
Introduction To Django
 
Django for Beginners
Django for BeginnersDjango for Beginners
Django for Beginners
 
Turbogears Presentation
Turbogears PresentationTurbogears Presentation
Turbogears Presentation
 
Behat - Drupal South 2018
Behat  - Drupal South 2018Behat  - Drupal South 2018
Behat - Drupal South 2018
 
How does get template part works in twenty ten theme
How does get template part works in twenty ten themeHow does get template part works in twenty ten theme
How does get template part works in twenty ten theme
 
Qpsmtpd
QpsmtpdQpsmtpd
Qpsmtpd
 
RSpec User Stories
RSpec User StoriesRSpec User Stories
RSpec User Stories
 
Create a web-app with Cgi Appplication
Create a web-app with Cgi AppplicationCreate a web-app with Cgi Appplication
Create a web-app with Cgi Appplication
 
Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Object Oriented PHP - PART-2
Object Oriented PHP - PART-2
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016
 
templates in Django material : Training available at Baabtra
templates in Django material : Training available at Baabtratemplates in Django material : Training available at Baabtra
templates in Django material : Training available at Baabtra
 
Django Interview Questions and Answers
Django Interview Questions and AnswersDjango Interview Questions and Answers
Django Interview Questions and Answers
 
Story Driven Development With Cucumber
Story Driven Development With CucumberStory Driven Development With Cucumber
Story Driven Development With Cucumber
 
Introduction To Lamp
Introduction To LampIntroduction To Lamp
Introduction To Lamp
 
Drupal 8: Huge wins, a Bigger Community, and why you (and I) will Love it
Drupal 8: Huge wins, a Bigger Community, and why you (and I) will Love itDrupal 8: Huge wins, a Bigger Community, and why you (and I) will Love it
Drupal 8: Huge wins, a Bigger Community, and why you (and I) will Love it
 

Similaire à DON’T RTFM - WTFM: Write the F--king Fantastic Manual

Hiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret SauceHiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret SauceJesse Vincent
 
Catalyst - refactor large apps with it and have fun!
Catalyst - refactor large apps with it and have fun!Catalyst - refactor large apps with it and have fun!
Catalyst - refactor large apps with it and have fun!mold
 
Practical catalyst
Practical catalystPractical catalyst
Practical catalystdwm042
 
Ch ch-changes cake php2
Ch ch-changes cake php2Ch ch-changes cake php2
Ch ch-changes cake php2markstory
 
The PHP mysqlnd plugin talk - plugins an alternative to MySQL Proxy
The PHP mysqlnd plugin talk - plugins an alternative to MySQL ProxyThe PHP mysqlnd plugin talk - plugins an alternative to MySQL Proxy
The PHP mysqlnd plugin talk - plugins an alternative to MySQL ProxyUlf Wendel
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practicesmanugoel2003
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreEngineor
 
Perl web programming
Perl web programmingPerl web programming
Perl web programmingJohnny Pork
 
Joomla! Day Chicago 2011 Presentation - Steven Pignataro
Joomla! Day Chicago 2011 Presentation - Steven PignataroJoomla! Day Chicago 2011 Presentation - Steven Pignataro
Joomla! Day Chicago 2011 Presentation - Steven PignataroSteven Pignataro
 
Heavy Web Optimization: Backend
Heavy Web Optimization: BackendHeavy Web Optimization: Backend
Heavy Web Optimization: BackendVõ Duy Tuấn
 
PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principlesPerl Careers
 
Build Your Own Instagram Filters
Build Your Own Instagram FiltersBuild Your Own Instagram Filters
Build Your Own Instagram FiltersTJ Stalcup
 
5 Reasons To Love CodeIgniter
5 Reasons To Love CodeIgniter5 Reasons To Love CodeIgniter
5 Reasons To Love CodeIgniternicdev
 
2019 StartIT - Boosting your performance with Blackfire
2019 StartIT - Boosting your performance with Blackfire2019 StartIT - Boosting your performance with Blackfire
2019 StartIT - Boosting your performance with BlackfireMarko Mitranić
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 
Starting with PHP and Web devepolment
Starting with PHP and Web devepolmentStarting with PHP and Web devepolment
Starting with PHP and Web devepolmentRajib Ahmed
 

Similaire à DON’T RTFM - WTFM: Write the F--king Fantastic Manual (20)

Hiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret SauceHiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret Sauce
 
Catalyst - refactor large apps with it and have fun!
Catalyst - refactor large apps with it and have fun!Catalyst - refactor large apps with it and have fun!
Catalyst - refactor large apps with it and have fun!
 
Practical catalyst
Practical catalystPractical catalyst
Practical catalyst
 
Ch ch-changes cake php2
Ch ch-changes cake php2Ch ch-changes cake php2
Ch ch-changes cake php2
 
2009-02 Oops!
2009-02 Oops!2009-02 Oops!
2009-02 Oops!
 
Ruby For Startups
Ruby For StartupsRuby For Startups
Ruby For Startups
 
The PHP mysqlnd plugin talk - plugins an alternative to MySQL Proxy
The PHP mysqlnd plugin talk - plugins an alternative to MySQL ProxyThe PHP mysqlnd plugin talk - plugins an alternative to MySQL Proxy
The PHP mysqlnd plugin talk - plugins an alternative to MySQL Proxy
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practices
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack Encore
 
Perl web programming
Perl web programmingPerl web programming
Perl web programming
 
Joomla! Day Chicago 2011 Presentation - Steven Pignataro
Joomla! Day Chicago 2011 Presentation - Steven PignataroJoomla! Day Chicago 2011 Presentation - Steven Pignataro
Joomla! Day Chicago 2011 Presentation - Steven Pignataro
 
Heavy Web Optimization: Backend
Heavy Web Optimization: BackendHeavy Web Optimization: Backend
Heavy Web Optimization: Backend
 
PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principles
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
 
Build Your Own Instagram Filters
Build Your Own Instagram FiltersBuild Your Own Instagram Filters
Build Your Own Instagram Filters
 
5 Reasons To Love CodeIgniter
5 Reasons To Love CodeIgniter5 Reasons To Love CodeIgniter
5 Reasons To Love CodeIgniter
 
2019 StartIT - Boosting your performance with Blackfire
2019 StartIT - Boosting your performance with Blackfire2019 StartIT - Boosting your performance with Blackfire
2019 StartIT - Boosting your performance with Blackfire
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Introduce Django
Introduce DjangoIntroduce Django
Introduce Django
 
Starting with PHP and Web devepolment
Starting with PHP and Web devepolmentStarting with PHP and Web devepolment
Starting with PHP and Web devepolment
 

Dernier

Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 

Dernier (20)

Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 

DON’T RTFM - WTFM: Write the F--king Fantastic Manual

  • 1. DON’T RTFM - WTFM Write the F--king Fantastic Manual
  • 2. Or how I learned to stop worrying and love the code
  • 3. or... Newbies write the best docs. I will teach you how to be a newbie all over again!
  • 4. My background Like most perl programmers I’m self taught But I learned very slowly since 1999 Why? Programming is 10% of my job and voluntary. Documentation assumes too much pre-existing knowledge
  • 5. My background - cont Teaching Statistics for science and business students They hate statistics, Why? How can I make them hate statistics less? The problem of contrived examples. Our goal is to prime them to deal with real world problems in the future.
  • 6. How did I solve this problem? Catalyst Catalyst::Manual::Tutorial didn’t work 12:23 <@kd> purl, doesn't work? 12:23 < purl> Look buddy, doesn't work is a strong statement. Does it sit on the couch all day? Is it making faces at you? Does it want more money? Is it sleeping with your girlfriend? Please be specific! Fixed in Catalyst 5.65: 21st Feb 2006 :13 months since the beginning of the project!
  • 7. Remove irrelevant information: created "MyApp" created "MyApp/script" - created "MyApp/lib" - created "MyApp/root" - created "MyApp/root/static" - created "MyApp/root/static/images" - created "MyApp/t" - created "MyApp/t/Model" - created "MyApp/t/View" - created "MyApp/t/Controller" - created "MyApp/lib/MyApp" - created "MyApp/lib/MyApp/Model" - created "MyApp/lib/MyApp/View" - created "MyApp/lib/MyApp/Controller" - created "MyApp/lib/MyApp.pm" - created "MyApp/Build.PL" - created "MyApp/Makefile.PL" - created "MyApp/README" - created "MyApp/Changes" - created "MyApp/t/01app.t" - created "MyApp/t/02pod.t" - created "MyApp/t/03podcoverage.t" - created "MyApp/root/static/images/catalyst_logo.png" - created "MyApp/root/static/images/btn_120x50_built.png" - created "MyApp/root/static/images/btn_120x50_built_shadow.png" - created "MyApp/root/static/images/btn_120x50_powered.png" - created "MyApp/root/static/images/btn_120x50_powered_shadow.png" - created "MyApp/root/static/images/btn_88x31_built.png" - created "MyApp/root/static/images/btn_88x31_built_shadow.png" - created "MyApp/root/static/images/btn_88x31_powered.png" - created "MyApp/root/static/images/btn_88x31_powered_shadow.png" - created "MyApp/root/favicon.ico" - created "MyApp/script/myapp_cgi.pl" - created "MyApp/script/myapp_fastcgi.pl" - created "MyApp/script/myapp_server.pl" - created "MyApp/script/myapp_test.pl" + ... output snipped created "MyApp/script/myapp_create.pl"
  • 8. Make the supplied code work: - sub greet : Local - { - my ($self, $context) = @_; + sub greet : Local { + my ($self, $c) = @_; - my $name = $context->req->params->{name}; - $context->log->debug("Got name: $namen"); + my $name = $c->req->param('name'); + $c->log->debug("Got name: $namen"); - if(!$name) - { - $context->stash->{message} = 'Please fill in a name!'; + if ($c->req->method eq 'POST') { + if(!$name) { + $c->stash->{message} = 'Please fill in a name!'; + } + else { + $c->stash->{message} = "Hello $name!"; } - else - { - $context->stash->{message} = "Hello $name!"; } - $context->stash->{template} = 'greet.tt'; + $c->stash->{template} = 'greet.tt'; }
  • 9. Show that the code works Always provide a reference implementation: The first fully working Catalyst Tutorial: http://dev.catalystframework.org/old-wiki/attachment/wiki/WikiStart/tutorial.tar.gz
  • 10. This set up the future of Catalyst Catalyst code is working code Catalyst educational material is always accompanied by working code.
  • 11. The original Catalyst tutorial lasted 9 months Kennedy Clark turned up and wrote a big tutorial A real published author :) (we have a history of these in Catalyst) On to the future
  • 13. Always give examples You can obtain the code for all the tutorial examples from the catalyst subversion repository by issuing the command: svn co http://dev.catalyst.perl.org/repos/Catalyst/tags/ examples/Tutorial/MyApp/5.7/ CatalystTutorial This will download the current code for each tutorial chapter in the CatalystTutorial directory. Each example application directory has the same name as the tutorial chapter.
  • 14. Reduce the barrier to entry Sometimes OSS programmers can seem hostile. Aim to only have to answer the same question once. Write the answer down In the pod In the wiki Teach the bot
  • 15. My most useful factoid 04:45 <@kd> purl, make_schema_at? 04:45 <+purl> make_schema_at is what i want 04:47 <@kd> no purl, make_schema_at is perl - MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:. /lib -e 'make_schema_at("My::Schema", { debug => 1, db_schema => "myschemaname", components => ["InflateColumn::DateTime"] }, ["dbi:Pg:host=localhost;dbname=mydbname", "user", "pass" ])' 04:47 <+purl> okay, kd.
  • 16. Summary: Always always always provide a working example. Use your tests as a basis if you want. Point the users to the tests in the pod if necessary. Why? To avoid constantly being asked stupid questions.
  • 17. If you don’t, what happens? Nobody cares because nobody uses your code. or: You’re constantly asked stupid questions or: If you’re lucky, someone like me comes along, asks the stupid questions, and writes the answers down. The third option doesn’t happen often.
  • 18. Cognitive Load Theory An educational technique used in school Maths and Science Education. KISS - Keep It Simple Stupid Working memory has a finite capacity: 7±2 items We should aim to ensure that only relevant items are presented to the reader, so their memory capacity isn’t overloaded.
  • 19. The Parts of Cognitive Load Intrinsic (internal) cognitive load: Task relevant demands e.g. Programming logic Extrinsic cognitive load: Business logic Prerequisite knowledge
  • 20. The components of software Programming logic Task logic Business logic Business logic can be big, complex and poorly defined.
  • 21. Add a dash of chaos theory e.g. a three parameter model with a single outcome variable can result in substantial divergence after a single change in initial conditions. It only needs 3 parameters to create chaos. Business logic always has > 3 parameters
  • 22. How to minimise chaos Make examples artificial and contrived. How do we do this without being boring and pointless?
  • 23. Case study. Catalyst Book LolCatalyst Translate snippets of text to LolCat. CPAN module: Acme::LOLCAT
  • 24. Educational purpose Show how to display a web page Show how to create a web service Show that authentication is possible Catalyst::Helper::AuthDBIC (or what I spent my time on when I visited Shadowcat to plan the book)
  • 25. Assumed knowledge Basic HTTP GET v POST requests Basic Perl data structures What’s an editor and how do I use it? How do I run a perl script? How do I install CPAN modules.
  • 26. Assumed knowledge cont. If the reader doesn’t possess the assumed knowledge the extrinsic and intrinsic cognitive load are both high.
  • 27. Authentication Authentication is complicated Instead of explaining it, I wrote a Catalyst::Helper that modifies an existing application Thank you PPI :) Problem solved in a single page of text.
  • 28. Web service Catalyst web services are simple In LolCatalyst/Controller/Root: sub translate_service : Local { my ($self, $c) = @_; $c->forward('translate'); $c->stash->{current_view} = 'Service'; } In LolCatalyst/View/Service: package LolCatalyst::View::Service; use strict; use base 'Catalyst::View::JSON'; __PACKAGE__->config({ expose_stash => [ qw/lol result/ ] }); 1;
  • 29. So far so good. No business logic Some programming logic Basic introduction to some core catalyst concepts
  • 30. A Controller with minimal business logic sub default :Path { my ( $self, $c ) = @_; $c->response->status(404); $c->response->body( 'Page not found' ); } sub translate :Local { my ($self, $c) = @_; my $lol = $c->req->body_params->{lol}; # only for a POST request # $c->req->params->{lol} would catch GET or POST # $c->req->query_params would catch GET params only $c->stash( lol => $lol, result => $c->model('Translate')->translate($lol), template => 'index.tt', ); } Assumed knowledge New knowledge
  • 31. Total number of concepts added View Service Dispatch
  • 32. We still have room for 4±2 Template View (almost identical to Service view) Model: package LolCatalyst::Lite::Model::Translate; use strict; use warnings; use parent 'Catalyst::Model'; use Acme::LOLCAT (); use Memoize; memoize ('translate'); sub translate { my ($self, $text) = @_; return Acme::LOLCAT::translate($text); } 1; Error trapping (in Controller::Root): sub end :ActionClass('RenderView') { my ($self, $c) = @_; my $errors = scalar @{$c->error}; if ($errors) { $c->res->status(500); $c->res->body('internal server error'); $c->clear_errors; } } Assumed knowledge Not very different from “normal” programing!
  • 33. The final result A very simple application Minimal extra learning required to understand the model Minimal programming logic features. What next?
  • 34. Get mst to refactor Let’s make a generic translation application. Many more moving parts. Large conceptual territory to cover How do we make sure that we only present relevant information to the reader? Git based education.
  • 35. Git - the other meaning Urbandictionary.com: A completely ignorant, childish person with no manners Total and utter tosser who is incapable of doing anything other than annoying people, and not in a way that is funny to others Means idiot or rotter. Often used affectionately like bugger, but when used seriously is probably more potent (but less rude) than the worst swear words.
  • 36. Git as an educational resource: the approach Each commit introduces a single new idea to the reader Advantages: Clarity Disadvantages: Labour intensive Need to rewrite history - story telling rather than “real” development But we can count the number of concepts introduced easily by looking at the diffs.
  • 37. Extending LolCatalyst review git history number of concepts per commit shows how clearly we have explained the problem
  • 38. Case study - Moose Cookbook The Moose cookbook is generally excellent and comprehensive. but ... The early examples are simple, but the become more complex quickly Where’s the code?
  • 39. Reducing complexity Reduce business logic reduce extrinsic cognitive load Simplify programming logic a delicate balance between being meaningful and too contrived
  • 40. package Point; package Point; use Moose; has 'x' => (isa => 'Int', is => 'rw', required => 1); has 'y' => (isa => 'Int', is => 'rw', required => 1); sub clear { my $self = shift; $self->x(0); $self->y(0); }
  • 41. package Point3D; package Point3D; use Moose; extends 'Point'; has 'z' => (isa => 'Int', is => 'rw', required => 1); after 'clear' => sub { my $self = shift; $self->z(0); };
  • 42. Where is the code - hidden in the pod=begin testing my $point = Point->new( x => 1, y => 2 ); isa_ok( $point, 'Point' ); isa_ok( $point, 'Moose::Object' ); is( $point->x, 1, '... got the right value for x' ); is( $point->y, 2, '... got the right value for y' ); $point->y(10); is( $point->y, 10, '... got the right (changed) value for y' ); dies_ok { $point->y('Foo'); } '... cannot assign a non-Int to y'; dies_ok { Point->new(); } '... must provide required attributes to new'; $point->clear(); is( $point->x, 0, '... got the right (cleared) value for x' ); is( $point->y, 0, '... got the right (cleared) value for y' ); # check the type constraints on the constructor ### the remaining test code is not relevant to the example ### and should be elsewhere!!!
  • 43. ALWAYS ADVERTISE YOUR EXAMPLES Unadvertised examples are extra extrinsic congnitive load
  • 44. ASSUME I WILL NEVER READ YOUR SOURCE CODE
  • 45. TIME TO WORK Contributors should get a copy of: http://github.com/singingfish/German-Perl-Documentation-Workshop or http://xrl.us/bhn6xm
  • 46. Task 1: Moose+DBIC Lots of interest in how to integrate Moose with DBIC No example driven documentation on how to do this No example driven documentation on why you want this Good starting material: DBIx::Class::Manual::Example http://localhost:2963/~frew/DBIx-Class-0.08122/ DBIx-Class-0.08122/lib/DBIx/Class/Manual/
  • 47. Task 2: Better explanation of Moose Roles Moose Roles The existing Cookbook Examples have too much business logic. There are inline test examples, but unadvertised http://localhost:2963/~flora/Moose-1.06/Moose-1.06/ lib/Moose/Cookbook/Roles/Recipe1.pod
  • 48. Task 3: Coercion Too confusing. Too much cognitive load Too many ways to do it? Show the simplest way Show a more flexible way Minimise business logic http://localhost:2963/~flora/Moose-1.06/Moose-1.06/lib/ Moose/Cookbook/Basics/Recipe5.pod
  • 49. Task 4: Better explanation of metaprogramming Why metaprogramming? Why make_immutable Why not make_immutable Where’s the simple example working code? http://localhost:2963/~flora/Moose-1.06/Moose-1.06/lib/ Moose/Cookbook/Meta/Recipe1.pod
  • 50. But ... I can’t write well I don’t speak good enough English. Catalyst Process: someone writes docs. kd reviews docs for content (major edits) the_jester reviews docs for grammar and spelling (minor edits) Your writing and language skills don’t matter because someone else will fix the problems
  • 51. Task 5: Moose::Manual::Index Let’s crowdsource! Read a moose perldoc page. Write down the names of the important concepts If you want write an explanation If you can’t work this out, just write the name of the concept Write a short explanation of the concept.
  • 52. Pod format Everyone read a Moose man page Each time you see a new concept, write it down: =head2 CONCEPT name of concept =head3 EXPLANATION what it does here =head3 MENTIONS where it’s mentioned elsewhere in the docs
  • 53. Patches welcome To the github repository Or patches/files to diment@gmail.com