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 m...
My background - cont
Teaching Statistics for science and business students
They hate statistics, Why?
How can I make them ...
How did I solve this problem?
Catalyst
Catalyst::Manual::Tutorial
didn’t work
12:23 <@kd> purl, doesn't work?
12:23 < purl...
Remove irrelevant information:
created "MyApp"
created "MyApp/script"
- created "MyApp/lib"
- created "MyApp/root"
- creat...
Make the supplied code work:
- sub greet : Local
- {
- my ($self, $context) = @_;
+ sub greet : Local {
+ my ($self, $c) =...
Show that the code works
Always provide a reference implementation:
The first fully working Catalyst Tutorial:
http://dev....
This set up the future of Catalyst
Catalyst code is working code
Catalyst educational material is always accompanied by
wo...
The original Catalyst tutorial lasted 9 months
Kennedy Clark turned up and wrote a big tutorial
A real published author :)...
The new tutorial
lib/Catalyst/Manual/Tutorial.pod
lib/Catalyst/Manual/Tutorial/Intro.pod
lib/Catalyst/Manual/Tutorial/Cata...
Always give examples
You can obtain the code for all the tutorial examples from the
catalyst subversion repository by issu...
Reduce the barrier to entry
Sometimes OSS programmers can seem hostile.
Aim to only have to answer the same question once....
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, ...
Summary:
Always always always provide a working example.
Use your tests as a basis if you want.
Point the users to the tes...
If you don’t, what happens?
Nobody cares because nobody uses your code.
or: You’re constantly asked stupid questions
or: I...
Cognitive Load Theory
An educational technique used in school Maths and Science
Education.
KISS - Keep It Simple Stupid
Wo...
The Parts of Cognitive Load
Intrinsic (internal) cognitive load:
Task relevant demands
e.g. Programming logic
Extrinsic co...
The components of software
Programming logic
Task logic
Business logic
Business logic can be big, complex and poorly defin...
Add a dash of chaos theory
e.g. a three parameter model with a
single outcome variable can result in
substantial divergenc...
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
C...
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...
Assumed knowledge cont.
If the reader doesn’t possess the assumed knowledge the
extrinsic and intrinsic cognitive load are...
Authentication
Authentication is complicated
Instead of explaining it, I wrote a Catalyst::Helper that modifies
an existin...
Web service
Catalyst web services are simple
In LolCatalyst/Controller/Root:
sub translate_service : Local {
my ($self, $c...
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->respons...
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::Trans...
The final result
A very simple application
Minimal extra learning
required to understand the
model
Minimal programming log...
Get mst to refactor
Let’s make a generic translation application.
Many more moving parts.
Large conceptual territory to co...
Git - the other meaning
Urbandictionary.com:
A completely ignorant, childish person with no manners
Total and utter tosser...
Git as an educational resource:
the approach
Each commit introduces a single new idea to the reader
Advantages:
Clarity
Di...
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 si...
Reducing complexity
Reduce business logic
reduce extrinsic cognitive load
Simplify programming logic
a delicate balance be...
package Point;
package Point;
use Moose;
has 'x' => (isa => 'Int', is => 'rw', required => 1);
has 'y' => (isa => 'Int', i...
package Point3D;
package Point3D;
use Moose;
extends 'Point';
has 'z' => (isa => 'Int', is => 'rw', required => 1);
after ...
Where is the code - hidden in
the pod=begin testing
my $point = Point->new( x => 1, y => 2 );
isa_ok( $point, 'Point' );
i...
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://...
Task 1: Moose+DBIC
Lots of interest in how to integrate Moose with DBIC
No example driven documentation on how to do this
...
Task 2: Better explanation of
Moose Roles
Moose Roles
The existing Cookbook Examples have too much business
logic.
There a...
Task 3: Coercion
Too confusing. Too much cognitive load
Too many ways to do it?
Show the simplest way
Show a more flexible...
Task 4: Better explanation of
metaprogramming
Why metaprogramming?
Why make_immutable
Why not make_immutable
Where’s the s...
But ...
I can’t write well
I don’t speak good enough English.
Catalyst Process:
someone writes docs.
kd reviews docs for c...
Task 5: Moose::Manual::Index
Let’s crowdsource!
Read a moose perldoc page.
Write down the names of the important concepts
...
Pod format
Everyone read a Moose man page
Each time you see a new concept, write it down:
=head2 CONCEPT
name of concept
=...
Patches welcome
To the github repository
Or patches/files to diment@gmail.com
Upcoming SlideShare
Loading in …5
×

Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010

739 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
739
On SlideShare
0
From Embeds
0
Number of Embeds
9
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010

  1. 1. DON’T RTFM - WTFM Write the F--king Fantastic Manual
  2. 2. Or how I learned to stop worrying and love the code
  3. 3. or... Newbies write the best docs. I will teach you how to be a newbie all over again!
  4. 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. 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. 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. 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. 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. 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. 10. This set up the future of Catalyst Catalyst code is working code Catalyst educational material is always accompanied by working code.
  11. 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
  12. 12. 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
  13. 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. 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. 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. 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. 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. 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. 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. 20. The components of software Programming logic Task logic Business logic Business logic can be big, complex and poorly defined.
  21. 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. 22. How to minimise chaos Make examples artificial and contrived. How do we do this without being boring and pointless?
  23. 23. Case study. Catalyst Book LolCatalyst Translate snippets of text to LolCat. CPAN module: Acme::LOLCAT
  24. 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. 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. 26. Assumed knowledge cont. If the reader doesn’t possess the assumed knowledge the extrinsic and intrinsic cognitive load are both high.
  27. 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. 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. 29. So far so good. No business logic Some programming logic Basic introduction to some core catalyst concepts
  30. 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. 31. Total number of concepts added View Service Dispatch
  32. 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. 33. The final result A very simple application Minimal extra learning required to understand the model Minimal programming logic features. What next?
  34. 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. 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. 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. 37. Extending LolCatalyst review git history number of concepts per commit shows how clearly we have explained the problem
  38. 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. 39. Reducing complexity Reduce business logic reduce extrinsic cognitive load Simplify programming logic a delicate balance between being meaningful and too contrived
  40. 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. 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. 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. 43. ALWAYS ADVERTISE YOUR EXAMPLES Unadvertised examples are extra extrinsic congnitive load
  44. 44. ASSUME I WILL NEVER READ YOUR SOURCE CODE
  45. 45. TIME TO WORK Contributors should get a copy of: http://github.com/singingfish/German-Perl-Documentation-Workshop or http://xrl.us/bhn6xm
  46. 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. 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. 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. 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. 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. 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. 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. 53. Patches welcome To the github repository Or patches/files to diment@gmail.com

×