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.
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
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.
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!!!
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