SlideShare a Scribd company logo
How to Make Your Users
Not Want to Murder You
Engineering Software Psychology
for the Lazy
Joe McMahon
joe.mcmahon@gmail.com
Lazy
Prepared to put in much effort now to save effort later
Psychological engineering?
Not “how to get things done”
engineering
“Things do not fall down around
your ears” engineering
“I’m so happy with this and I trust
it” engineering
Isn’t this “user experience”?
Sort of
Focus on very specific ways of thinking and
communicating
“Soft” approach
“Warm fuzzies” and “cold pricklies”
Cues and messages
Managing expectations
“Unix is user-friendly; it’s
just selective about who its
friends are.”
Good programming != good
“soft science” engineering
Engineers tend to build “safe for engineers”
Need to balance “useful for experts” and “safe for
non-experts”
How to make your users not want to murder you
Case Study:
WWW::Mechanize
I
WWW::Mechanize
my $mech = WWW::Mechanize->new();
$mech->get($some_url);
if($mech->success) {
...
}
We’ve all seen this
WWW::Mechanize-1.49_01
But...
[THINGS THAT MAY BREAK YOUR CODE]
The autocheck argument to the constructor is now ON by
default, unless WWW::Mechanize is being subclassed.
There are so many new programmers whose ->get() calls
fail unchecked that I'm now putting on the seat belts for
them.
[THINGS THAT MAY BREAK YOUR CODE]
The autocheck argument to the constructor is now ON by
default, unless WWW::Mechanize is being subclassed.
There are so many new programmers whose ->get() calls
fail unchecked that I'm now putting on the seat belts for
them.
[THINGS THAT MAY BREAK YOUR CODE]
The autocheck argument to the constructor is now ON by
default, unless WWW::Mechanize is being subclassed.
There are so many new programmers whose ->get() calls
fail unchecked that I'm now putting on the seat belts for
them.
[THINGS THAT MAY BREAK YOUR CODE]
The autocheck argument to the constructor is now ON by
default, unless WWW::Mechanize is being subclassed.
There are so many new programmers whose ->get() calls
fail unchecked that I'm now putting on the seat belts for
them.
[THINGS THAT ARE TOTALLY GOING TO BREAK WORKING
CODE FOR NO OBVIOUS REASON]
The autocheck argument to the constructor is now ON by default,
unless WWW::Mechanize is being subclassed. There are so
many new programmers whose ->get() calls fail unchecked that
I'm now putting on the seat belts for them. Your code will die
instead of recovering. You will need to make changes to avoid
this.
my $mech = WWW::Mechanize->new();
$mech->get($some_url); # <- DEATH
if($mech->success) {
...
}
Canonical example now breaks
my $mech = WWW::Mechanize::Firefox->new();
$mech->get($some_url); # <- NOT DEATH
if($mech->success) {
...
}
Except when it doesn’t
Error GETing http://your-uri: reason
Technically accurate
Psychologically incomplete
Sudden surprise result
“You’re holding it wrong.”
It was great...
...unless there was an error.
How to make your users not want to murder you
Latest one I could find: June 4, 2012
Why?
Complacency part 1:
too much awesome
Previous “major-ish” Mech changes
Make things that you should have been doing
anyway mandatory
Remove deprecated features that were
already generating deprecation warnings
I figure it's about time we hit 1.00, and this version seems
like a good place to do it, because of the potential breakage
described below...
[THINGS THAT WILL BREAK YOUR CODE]
* Header handling has changed. There is no more package variable
%headers that holds all the headers to be added. They are
now added on a per-object basis.
Last major change
“use strict” saved you
Complacency part 2:
out-of-date docs
WWW::Mechanize::Cookbook had an autocheck note
from day 1
Already-in-print (and usually at-hand and first-
checked) books did not!
WWW::Mechanize::Examples still doesn’t all have
autocheck=>1 as of April 2013 (2 out of 10 use it)
Spidering Hacks: 100 Industrial-Strength Tips & Tools - Page 61 - Google Books Result
books.google.com/books?isbn=0596005776
Kevin Hemenway, Tara Calishain - 2004 - Computers
WWW::Mechanize 101 Using Mech's Navigation Tools So far, Mech is just a ... starting search page $mech->get( "http://search.cpan.org" ); $mech->success or ...
Mechanize.pm - CPAN - Perl.org
cpansearch.perl.org/src/.../Test...Mechanize-1.../Mechanize.pmShare
... tests => 5; use WWW::Mechanize; my $mech = WWW::Mechanize->new; $ mech->get( $page ); ok( $mech->success ); is( $mech->base, 'http://petdance. com', ...
lib/Drupal/Admin.pm - The CPAN Search Site
cpansearch.perl.org/src/DURIST/Drupal-Admin.../Admin.pmShare
'?q=user'; $self->mech->get($url); $self->_die("Failed to get login page: " . $self-> mech->response->status_line) unless $self->mech->success; ...
Hack 21. WWW::Mechanize 101
spideringhacks.org.ua/0596005776_spiderhks-chp-2-sect-17....Share
Now that Mech is working for me, I don't even have to deal with any HTTP:: Response objects unless I specifically want to. The success method checks that the ...
Drupal2wiki - GMOD
www.gmod.org/wiki/Drupal2wikiShare
Oct 8, 2012 – ... (@urls) { $mech->get( $url_to_convert ); warn "could not get page: $ url_to_convert" unless $mech->success(); next unless $mech->success() ...
WWW::Mechanize::Examples - search.cpan.org
search.cpan.org › Jesse Vincent › WWW-Mechanize-1.72Share
But thanks to mech, all I had to do was `. ... fields => { password => $password }, ) ; die unless ($mech->success); # upload image files specified on command line ...
C:CVSCheckoutsscscrape.pl.html
www.cs.cmu.edu/~maverick/Programs/.../scrape.pl.htmlShare
n"; binmode F; print F $mech->content(); close F; print " OK"; } else { $failure++; print " Failed"; } } print "n"; } # wrap up print "Finished downloading $success ...
Google results out of date
www::mechanize
example -ruby
176,000 hits
Most
still don’t turn off autocheck
use $mech->success()
No lead up to the change in the code
No meta-messaging
Hard to map from error to cause
Common use case most likely broken
Summarized psychological failures
“Everything you know is wrong”
“My production code is broken
because a module changed?”
Communications
Primary psychological engineering job
Imperative that everyone gets the message
But most other (and more often referenced) sources
say to do something wrong
How do we communicate a change like this to a large
set of people?
Tool #1 - Increment major version
Tool #2 - Accurately diagnose the failure
so it is psychologically complete
Error GETing http://cantreachthis.com: Page not found
(You didn't specify 'autocheck' in new(); use 'autocheck => 1' to
if you want to check status yourself.)
Tool #3 - Warn if requirements not met
(with a psychologically complete diagnostic)
my $mech = WWW::Mechanize->new();
Warning: Non-subclassed WWW::Mechanize
objects now default to autocheck=>1 at foo.pl
line 9.
Tool #4 - Allow old code to work via inconvenient hack
# Could also set this in the shell...
$ENV{I_AM_IGNORING_THE_MECH_AUTOCHECK_REQUI
REMENT} = 1;
my $mech = WWW::Mechanize->new();
$mech->get($some_url);
if ($mech->success) {
...
}
Warning: autocheck=>1 overridden at line 6 in myscript.pl.
Tool #5 - Obvious documentation
Prior to anything in the USAGE section
Actually use it properly in the SYNOPSIS
“HEY YOU - IMPORTANT API CHANGE”
What were the sources of failure?
Perspective
Unintended consequences
Preparation
Deployment
Diagnosis
Rescue
Psychological engineering bases
Protection + Communication
Blog
Email
Twitter
Mailing lists
Websites
...repeatedly
Preparation
Man page
Changelog
Checkin comments
Error messages
Deployment
Show the error early
Better to die in new()
than fail later
Diagnosis
Say exactly why
Compile time beats
run time
if ($ENV{I_AM_IGNORING_THE_MECH_AUTOCHECK_REQUIREMENT}) {
...
}
Rescue
Make the situation obvious
What it is
Short-term fix
Long-term fix
Fallback if possible
How to make your users not want to murder you
“Coddling” is a good thing
Widely-used module
One of the “really good Perl things”
Potential for long-delayed error
Adds up to “you don’t want this to happen”
“It’s stupid to just upgrade.”
“You’re holding it wrong.”
How to make your users not want to murder you
Reasonable “not so smart”
Sleepy == not smart at all
Increasing order of usability
“You got this error”
“You got this error,
here’s why
and how to fix it”
“You got an error”
Silence
Goal of psychological
engineering
Questions?
Discussion?
Thanks

More Related Content

PDF
H4x0rs gonna hack
PDF
YUI introduction to build hack interfaces
PDF
2013 05-03 - HTML5 & JavaScript Security
PDF
Getting touchy - an introduction to touch events / Web Standards Days / Mosco...
PDF
Clearance: Simple, complete Ruby web app authentication.
PDF
Passwords and freedom: can we lose the former and retain the latter?
PDF
ILUG 2010 - Deploying plug-ins to the enterprise
PPT
YUI for your Hacks-IITB
H4x0rs gonna hack
YUI introduction to build hack interfaces
2013 05-03 - HTML5 & JavaScript Security
Getting touchy - an introduction to touch events / Web Standards Days / Mosco...
Clearance: Simple, complete Ruby web app authentication.
Passwords and freedom: can we lose the former and retain the latter?
ILUG 2010 - Deploying plug-ins to the enterprise
YUI for your Hacks-IITB

What's hot (20)

PDF
Professional web development with libraries
ODP
Web Security
PDF
jQuery: Events, Animation, Ajax
PDF
Take My Logs. Please!
PDF
Creating Responsive Experiences
PPTX
Sql Injections With Real Life Scenarious
PPT
Pubcon Las Vegas 2012 SQL Injection
PDF
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
TXT
Vidéo approche en immobilier
PDF
6.2. Hacking most popular websites
PDF
Leave No One Behind with HTML5 - FFWD.PRO, Croatia
PDF
6.Web Servers
PDF
Practical django secuirty
PDF
How to Uninstall and Reinstall WordPress
KEY
Bestpractices nl
PDF
You don't know people
PDF
Helping Data Teams with Puppet / Puppet Camp London - Apr 13, 2015
PPTX
Simple web security
PDF
YUI on the go
PPT
Simple way to Remove Accurately locate.com
Professional web development with libraries
Web Security
jQuery: Events, Animation, Ajax
Take My Logs. Please!
Creating Responsive Experiences
Sql Injections With Real Life Scenarious
Pubcon Las Vegas 2012 SQL Injection
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
Vidéo approche en immobilier
6.2. Hacking most popular websites
Leave No One Behind with HTML5 - FFWD.PRO, Croatia
6.Web Servers
Practical django secuirty
How to Uninstall and Reinstall WordPress
Bestpractices nl
You don't know people
Helping Data Teams with Puppet / Puppet Camp London - Apr 13, 2015
Simple web security
YUI on the go
Simple way to Remove Accurately locate.com
Ad

Similar to How to make your users not want to murder you (20)

PDF
Intro to Php Security
PDF
Revoke-Obfuscation
PDF
Workshop: Functional testing made easy with PHPUnit & Selenium (phpCE Poland,...
PDF
Windows attacks - AT is the new black
PDF
Windows Attacks AT is the new black
KEY
Ruby For Startups
PDF
Lean Php Presentation
PDF
Penetration Testing for Easy RM to MP3 Converter Application and Post Exploit
PDF
My app is secure... I think
PDF
Modern tooling to assist with developing applications on FreeBSD
PPTX
Testing Terraform
ODP
My app is secure... I think
PDF
OSCP Preparation Guide @ Infosectrain
PPTX
Sherlock Homepage - A detective story about running large web services - WebN...
PDF
Whatever it takes - Fixing SQLIA and XSS in the process
ODP
My app is secure... I think
PDF
Applications secure by default
PDF
Applications secure by default
PPTX
Random numbers
PDF
Reutov, yunusov, nagibin random numbers take ii
Intro to Php Security
Revoke-Obfuscation
Workshop: Functional testing made easy with PHPUnit & Selenium (phpCE Poland,...
Windows attacks - AT is the new black
Windows Attacks AT is the new black
Ruby For Startups
Lean Php Presentation
Penetration Testing for Easy RM to MP3 Converter Application and Post Exploit
My app is secure... I think
Modern tooling to assist with developing applications on FreeBSD
Testing Terraform
My app is secure... I think
OSCP Preparation Guide @ Infosectrain
Sherlock Homepage - A detective story about running large web services - WebN...
Whatever it takes - Fixing SQLIA and XSS in the process
My app is secure... I think
Applications secure by default
Applications secure by default
Random numbers
Reutov, yunusov, nagibin random numbers take ii
Ad

Recently uploaded (20)

PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
Machine Learning_overview_presentation.pptx
PPTX
cloud_computing_Infrastucture_as_cloud_p
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Getting Started with Data Integration: FME Form 101
PDF
Mushroom cultivation and it's methods.pdf
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
A comparative study of natural language inference in Swahili using monolingua...
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
Tartificialntelligence_presentation.pptx
PPTX
SOPHOS-XG Firewall Administrator PPT.pptx
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPTX
Programs and apps: productivity, graphics, security and other tools
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Digital-Transformation-Roadmap-for-Companies.pptx
Agricultural_Statistics_at_a_Glance_2022_0.pdf
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Machine Learning_overview_presentation.pptx
cloud_computing_Infrastucture_as_cloud_p
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Getting Started with Data Integration: FME Form 101
Mushroom cultivation and it's methods.pdf
Diabetes mellitus diagnosis method based random forest with bat algorithm
A comparative study of natural language inference in Swahili using monolingua...
Building Integrated photovoltaic BIPV_UPV.pdf
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Tartificialntelligence_presentation.pptx
SOPHOS-XG Firewall Administrator PPT.pptx
gpt5_lecture_notes_comprehensive_20250812015547.pdf
Mobile App Security Testing_ A Comprehensive Guide.pdf
Per capita expenditure prediction using model stacking based on satellite ima...
Programs and apps: productivity, graphics, security and other tools

How to make your users not want to murder you

  • 1. How to Make Your Users Not Want to Murder You Engineering Software Psychology for the Lazy Joe McMahon [email protected]
  • 2. Lazy Prepared to put in much effort now to save effort later
  • 3. Psychological engineering? Not “how to get things done” engineering “Things do not fall down around your ears” engineering “I’m so happy with this and I trust it” engineering
  • 4. Isn’t this “user experience”? Sort of Focus on very specific ways of thinking and communicating
  • 5. “Soft” approach “Warm fuzzies” and “cold pricklies” Cues and messages Managing expectations
  • 6. “Unix is user-friendly; it’s just selective about who its friends are.”
  • 7. Good programming != good “soft science” engineering Engineers tend to build “safe for engineers” Need to balance “useful for experts” and “safe for non-experts”
  • 11. my $mech = WWW::Mechanize->new(); $mech->get($some_url); if($mech->success) { ... } We’ve all seen this
  • 13. [THINGS THAT MAY BREAK YOUR CODE] The autocheck argument to the constructor is now ON by default, unless WWW::Mechanize is being subclassed. There are so many new programmers whose ->get() calls fail unchecked that I'm now putting on the seat belts for them.
  • 14. [THINGS THAT MAY BREAK YOUR CODE] The autocheck argument to the constructor is now ON by default, unless WWW::Mechanize is being subclassed. There are so many new programmers whose ->get() calls fail unchecked that I'm now putting on the seat belts for them.
  • 15. [THINGS THAT MAY BREAK YOUR CODE] The autocheck argument to the constructor is now ON by default, unless WWW::Mechanize is being subclassed. There are so many new programmers whose ->get() calls fail unchecked that I'm now putting on the seat belts for them.
  • 16. [THINGS THAT MAY BREAK YOUR CODE] The autocheck argument to the constructor is now ON by default, unless WWW::Mechanize is being subclassed. There are so many new programmers whose ->get() calls fail unchecked that I'm now putting on the seat belts for them.
  • 17. [THINGS THAT ARE TOTALLY GOING TO BREAK WORKING CODE FOR NO OBVIOUS REASON] The autocheck argument to the constructor is now ON by default, unless WWW::Mechanize is being subclassed. There are so many new programmers whose ->get() calls fail unchecked that I'm now putting on the seat belts for them. Your code will die instead of recovering. You will need to make changes to avoid this.
  • 18. my $mech = WWW::Mechanize->new(); $mech->get($some_url); # <- DEATH if($mech->success) { ... } Canonical example now breaks
  • 19. my $mech = WWW::Mechanize::Firefox->new(); $mech->get($some_url); # <- NOT DEATH if($mech->success) { ... } Except when it doesn’t
  • 25. ...unless there was an error.
  • 27. Latest one I could find: June 4, 2012
  • 28. Why?
  • 29. Complacency part 1: too much awesome
  • 30. Previous “major-ish” Mech changes Make things that you should have been doing anyway mandatory Remove deprecated features that were already generating deprecation warnings
  • 31. I figure it's about time we hit 1.00, and this version seems like a good place to do it, because of the potential breakage described below... [THINGS THAT WILL BREAK YOUR CODE] * Header handling has changed. There is no more package variable %headers that holds all the headers to be added. They are now added on a per-object basis. Last major change “use strict” saved you
  • 32. Complacency part 2: out-of-date docs WWW::Mechanize::Cookbook had an autocheck note from day 1 Already-in-print (and usually at-hand and first- checked) books did not! WWW::Mechanize::Examples still doesn’t all have autocheck=>1 as of April 2013 (2 out of 10 use it)
  • 33. Spidering Hacks: 100 Industrial-Strength Tips & Tools - Page 61 - Google Books Result books.google.com/books?isbn=0596005776 Kevin Hemenway, Tara Calishain - 2004 - Computers WWW::Mechanize 101 Using Mech's Navigation Tools So far, Mech is just a ... starting search page $mech->get( "http://search.cpan.org" ); $mech->success or ... Mechanize.pm - CPAN - Perl.org cpansearch.perl.org/src/.../Test...Mechanize-1.../Mechanize.pmShare ... tests => 5; use WWW::Mechanize; my $mech = WWW::Mechanize->new; $ mech->get( $page ); ok( $mech->success ); is( $mech->base, 'http://petdance. com', ... lib/Drupal/Admin.pm - The CPAN Search Site cpansearch.perl.org/src/DURIST/Drupal-Admin.../Admin.pmShare '?q=user'; $self->mech->get($url); $self->_die("Failed to get login page: " . $self-> mech->response->status_line) unless $self->mech->success; ... Hack 21. WWW::Mechanize 101 spideringhacks.org.ua/0596005776_spiderhks-chp-2-sect-17....Share Now that Mech is working for me, I don't even have to deal with any HTTP:: Response objects unless I specifically want to. The success method checks that the ... Drupal2wiki - GMOD www.gmod.org/wiki/Drupal2wikiShare Oct 8, 2012 – ... (@urls) { $mech->get( $url_to_convert ); warn "could not get page: $ url_to_convert" unless $mech->success(); next unless $mech->success() ... WWW::Mechanize::Examples - search.cpan.org search.cpan.org › Jesse Vincent › WWW-Mechanize-1.72Share But thanks to mech, all I had to do was `. ... fields => { password => $password }, ) ; die unless ($mech->success); # upload image files specified on command line ... C:CVSCheckoutsscscrape.pl.html www.cs.cmu.edu/~maverick/Programs/.../scrape.pl.htmlShare n"; binmode F; print F $mech->content(); close F; print " OK"; } else { $failure++; print " Failed"; } } print "n"; } # wrap up print "Finished downloading $success ... Google results out of date
  • 34. www::mechanize example -ruby 176,000 hits Most still don’t turn off autocheck use $mech->success()
  • 35. No lead up to the change in the code No meta-messaging Hard to map from error to cause Common use case most likely broken Summarized psychological failures “Everything you know is wrong”
  • 36. “My production code is broken because a module changed?”
  • 37. Communications Primary psychological engineering job Imperative that everyone gets the message But most other (and more often referenced) sources say to do something wrong How do we communicate a change like this to a large set of people?
  • 38. Tool #1 - Increment major version
  • 39. Tool #2 - Accurately diagnose the failure so it is psychologically complete Error GETing http://cantreachthis.com: Page not found (You didn't specify 'autocheck' in new(); use 'autocheck => 1' to if you want to check status yourself.)
  • 40. Tool #3 - Warn if requirements not met (with a psychologically complete diagnostic) my $mech = WWW::Mechanize->new(); Warning: Non-subclassed WWW::Mechanize objects now default to autocheck=>1 at foo.pl line 9.
  • 41. Tool #4 - Allow old code to work via inconvenient hack # Could also set this in the shell... $ENV{I_AM_IGNORING_THE_MECH_AUTOCHECK_REQUI REMENT} = 1; my $mech = WWW::Mechanize->new(); $mech->get($some_url); if ($mech->success) { ... } Warning: autocheck=>1 overridden at line 6 in myscript.pl.
  • 42. Tool #5 - Obvious documentation Prior to anything in the USAGE section Actually use it properly in the SYNOPSIS “HEY YOU - IMPORTANT API CHANGE”
  • 43. What were the sources of failure?
  • 50. Show the error early Better to die in new() than fail later Diagnosis Say exactly why Compile time beats run time
  • 52. Make the situation obvious What it is Short-term fix Long-term fix Fallback if possible
  • 54. “Coddling” is a good thing Widely-used module One of the “really good Perl things” Potential for long-delayed error Adds up to “you don’t want this to happen”
  • 55. “It’s stupid to just upgrade.”
  • 59. Sleepy == not smart at all
  • 60. Increasing order of usability “You got this error” “You got this error, here’s why and how to fix it” “You got an error” Silence

Editor's Notes

  • #2: What would cause my users to be so upset as all that?
  • #6: This will be very seat-of-the-pants, intuitve stuff “Beginners mind” Feelings rather than measurements Information about essences rather than details Should feel confident when using; should feel doubtful when appropriate
  • #9: Psychologically engineered Simple to work with for safe things Psychological barriers for unsafe ones (four steps with three warnings to erase the phone)
  • #10: Let’s do a case study of a good software decision but a bad psychological one One of the most popular and most used modules in CPAN Heavily used, much written about it The ‘go-to’ heavy-lifting module for Web interaction
  • #11: A very, very specific disclaimer: None of the following is meant to say anything bad about Mech, or Andy, or anyone else who has worked on Mech It’s great, I use it, it got me a job writing Web automation software This talk is meant to point out how a small failure in psychological engineering can cause a surprising amount of trouble
  • #12: Canonical example. Documented this way in hundreds of places. All over the net. Lots of books. Especially in the Perl Cookbook. Very standard, ver Perlish, like open(): try the operation, did it work, continue if so
  • #13: As of this release, something happened that breaks these examples.
  • #14: Here’s the note in the Changelog (As an aside: this is a minor engineering psychology misstep: non-engineers skip the changelogs and install things first)
  • #16: New programmers who are not checking the get() calls are unfortunately the people who aren’t reading this!
  • #17: Great software fix. Not as good psychological engineering because the audience this is intended for hasn’t read this and is not going to notice the change. It also doesn’t mention the actual consequence of the change!
  • #18: So this is the real meaning.
  • #19: If the get fails, you no longer get to check the status; get() dies. That’s what autocheck does, and now it’s on by default. This is code “that was just working yesterday, what happened?”
  • #20: Unless you’re using a subclass and in that case it isn’t. Inconsistency leads to confusion and is a “cold pricklies” generator. Code that looks identical at the point of use behaves differently.
  • #22: A failure occurred, but what do I do now, if I am new to Perl, or a dabbler? All I need to do is add autocheck=>1 ... but I need to know that I need to do that.
  • #23: Users who had working code, sometimes production code, suddenly had broken code. Worse, they only had broken code in an exceptional situation: if the get() worked, almost all the time, they’d never see the problem. The API had changed in a subtle way that was not automatically caught if you upgraded the library. Remember that often one person is responsible for the script, and another for keeping packages up to date. In a situation like this, it’s only possible but likely that this would happen. (It happened a LOT at Yahoo!) But surely this was only a problem till the message got out...
  • #24: Another example (from a surprising source) of bad psychological engineering. If you held the iPhone 4 the way you were used to, you’d interfere with the antenna. This was the first response. The second was the free cases program.
  • #25: The best psychological engineering would have ensured that any attempt to “hold it wrong” would have quickly informed the user of potential problems - especially if “standard”examples could trigger the problem. Most of the time there was no awareness that there was a problem...
  • #26: Surely, though, this isn’t REALLY a problem. Right?
  • #27: As of 2012, it still was, especially to new programmers, who for some reason were still not expecting this “helpful” behavior. (And the answer here is also technically correct ... but psychologically incorrect. Actually showing how to turn autocheck off would have yielded “warm fuzzies”.)
  • #28: Seems to have tailed off now; I can’t find any more-recent failures, which is good! But this still means that it took 4 *years* to get to this point!
  • #29: If you’re thinking solely as a programmer this makes no sense. The WWW::Mechanize Cookbook had this in examples on day 1 of the release Why did it take 4 years? Why did it happen at all? Why didn’t the message get across? Why was it missed and why did it continue to be missed?
  • #30: We’ve had many, many releases of the module and my code continued to work fine. Why should this one be any different? Mech is awesome, it just works! (Huge amounts of warm fuzzies, leading to) It’s so great, I’ll use it for everything! Like the recovery script I run when there’s a problem! Or my quick health-check script! Or lots of other things I don’t use too often!
  • #31: Contributing to complacency: - previous changes had been more thoroughly pre-tracked and pre-announced (good psychological engineering!) This one was different - autocheck wasn’t optional prior to its introduction, and there was not “you didn’t use autocheck” deprecation period
  • #32: This was the major change. Note that it didn’t have any hidden behavior: if you (sensibly) had use strict on and tried to access %headers, you’d die at compile time (handwaving eval’s). Great psychology! We’re going to make a change with potential breakage, so we’ll send the signal via the version number too. Some points: - bumping the version to 1.00 is expectation management. - The change would NOT cause an error at run time, but compile time (some pricklies, but not late-night-oh-crap-why-is-this-broken-it-was-working-last-time pricklies)
  • #33: Yes, I should submit a patch. I promise I will after this session.
  • #34: Here’s a number of relevant hits from a quick Google of Mech->success (5M hits). Only the Mech examples use autocheck explicitly.
  • #37: This generally summarizes how my users felt about it.
  • #38: We need to tell thousands of people, likely running many scripts each, to make this fix in every one of those scripts How can we do that in a way that does not irritate them while keeping the message in front of them? We need to send the message through as many channels as possible at once We need to communicate as directly to the affected people as possible
  • #39: A meta-message, fairly standard in the Perl community (this is why you see things like version 1.294) For the maintainer, a pure engineering solution, with no code involved. Warm fuzzies from knowing something big happened.
  • #40: Tell me what is wrong. Don’t make me guess or have to find that mention in the docs. Very direct messaging: here at this place in this code, this specific thing needs doing. Relatively minor software effort; just a longer message. A little bit of wording needed to convey the right impression. The programmer cared enough to tell me how to fix this, so I can just get it it done in a few seconds. Huge warm fuzzies.
  • #41: Alternate: at least tell us that a new default is now in force. Doesn’t stop the error but at least lets us know that it can happen. A very simple check, but more intrusive than the expanded die(). A little less programmer-friendly; those who “know better” and “just want to use the module” will get warnings. Appropriate cold pricklies, with an admixture of “you should know” warm fuzzies.
  • #42: A useful mitigation: code doesn’t have to be updated yet; we can do back to the old behavior until the problem can be corrected properly. A long name encourages fixing it properly, and a cleverly chosen one is a reminder at the same time. More social than software, though this adds more maintenance burden - the old and new code have to coexist. Extra-warm fuzzies for being able to get old code to work without changing it.
  • #43: Emphasize the change; because this changes away from the original default (check actions for success), make sure that anyone even glancing at the man page sees this. Not quite as effective, but more likely to catch people’s eye when they go to the docs when they get an error. Purely a psychological change, not supported in the software; not as good as it’s not at the point of the error, but has the advantage of possibly forestalling the error happening at all. Warm fuzzies if seen; more likely to be seen if done this way.
  • #44: Let’s take a minute to look at why none of these things were done. Again, this is LEARNING FROM HISTORY, not blame.
  • #45: Many of the bug reports from WWW::Mechanize were caused by people not calling $mech->success in the pre-autocheck era From the author’s perspective fixing this is very important as it’s a large source of bogus errors
  • #46: (Here were looking at erosion caused by rabbits in Australia.) The solution fixed a problem that the author had very well But it created a secondary one by sometimes breaking old code And a tertiary one by not making it dead simple to recover from that
  • #47: These are all meant to communicate to prevent a problem and to provide quick recovery in case one happens anyway.
  • #48: We need to consider both old code and new code, and work out ways to protect all of our users.
  • #49: Announce and engage - both before and after the change - Blog about the change; writing an explanation may help you spot an oversight - send email to your user mailing lists (you should have one that people can subscribe to) - Announce the upcoming change in public areas: Twitter, Perlmonks, etc.
  • #50: Communicate! - emphasize the change in the changelog (done, but maybe not as much as needed) - put it up front in the man page (ideally at the very beginning so we don’t have to count on users reading far enough to see it) - put it in the commit; this gives you a chance that someone else following the commits will spot the assumptions and tell you - update errors to make sure that new errors explain why they are there
  • #51: If a common idiom is different, warn or die as early as possible. Better to die in new() with a diagnostic spelling out the problem than to only die in exceptional situations without a full description of why.
  • #52: There is a workaround, but not a convenient one A variable like this helps emphasize that you haven’t done that you need to do Second, it’s a pain to use, so you want to fix it ASAP
  • #53: Make sure that what to do about it is clear Add a section to the docs specifically about what the change is and what is does in all cases If there’s a hack to get around it, document it here (“add autocheck=>0” to all new calls, or subclass WWW::Mechanize) Spell out what needs to change to be compatible with the new function (all new code needs to expect that GET/POST will die instead of setting a failed status)
  • #54: I initially posted a meditation about this on Perlmonks. The response was almost unanimous that I was over-coddling my users.
  • #56: Another camp focused on the psychological problem, but solely as software developers.
  • #57: It’s true, but being right about procedure does not fix the problem. What are the reasons it could happen in the first place?
  • #58: You’ve got a deadline, you’re rushed, you’re updating other modules; take a quick look, looks fine, install it. Oops, some time later. You got distracted while reading the install docs and missed it, or it flew by in a giant CPAN install. You’re under pressure to get a new version up because you’re behind and this version fixes bugs that you’re hitting. You’re maybe not that smart at the moment it comes time to make the decision.
  • #59: This is not necessarily because you are dumb! I like to shoot for about how smart I think I am at 2AM. If something like this goes bad, it almost always happens after hours and after I’m asleep. I am very not smart when I’ve woken up out of a deep sleep - many people aren’t.
  • #60: Flight officer fell asleep for 75 minutes and woke up disoriented and “not feeling well”. An unusual situation occurred, and he reacted improperly because of sleepiness, not inability. Several passengers were injured.
  • #61: What we want is enhanced usability for those kind of times. Not hand-holding, but completeness and accuracy. At 2AM I need that little extra help and reminder. It’s not expensive to do, so I do it as a safety issue This engenders trust.
  • #62: This is how users should feel about your code. If an error occurs, it’s real, not an “oh by the way I changed this, sorry”.