Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Simple Ways To Be A Better Programmer (OSCON 2007)

"Simple Ways To Be A Better Programmer' as presented at OSCON 2007 by Michael G Schwern.

The audio is still out of sync, working on it. Downloading will be available once the sync is done.

  • Be the first to comment

Simple Ways To Be A Better Programmer (OSCON 2007)

  1. 1. Simple Ways To Be A Better Programmer Michael G Schwern schwern@pobox.com
  2. 2. Discussion Session D135 @ 5:30pm
  3. 3. #!/usr/bin/perl -s $;=$/;seek+DATA,!++$/,!$s;$_=<DATA>;$s&&print||$g&&do{$y=($x||=20)*($y||8);sub i{sleep&f}sub'p{print$;x$=,join$;,$b=~/.{$x}/g}$j=$j;sub'f{pop}sub n{substr($b,&f%$y,3)=~tr,O,O,}sub'g{$f=&f-1;($w,$w,substr($b,&f,1),O)[n($f-$x)+ n($x+$f)-(substr($b,&f,1)eq+O)+n$f]||$w}$w=quot;40quot;;$b=join'',@ARGV?<>:$_,$w x$y;$b=~s).)$&=~/w/?O:$w)ge;substr($b,$y)=q++;$g='$i=0;$i?$b:$c=$b; substr+$c,$i,1,g$i;$g=~s?d+?($&+1)%$y?e;$i-$y+1?eval$g:do{$i=-1;$b=$c;p;i 1}';sub'e{eval$g;&e}e}||eval||die+No.$; __DATA__ if($j){{$^W=$|;*_=sub{$=+s=#([A-z])(.*)#=#$+$1#=g}} @s=(q[$_=sprintf+pop@s,@s],q[ if($j){{$^W=$|;*_=sub{$=+s=#([A-z])(.*)#=#$+$1#=g}} #_The_Perl_Journal_# @s=(q[%s],q[%s])x2;%s;printquot;nquot;x&_,$_;i$j;eval} ])x2;$_=sprintf+pop@s,@s;printquot;nquot;x&_,$_;i$j;eval}$/=$y;$quot;=quot;,quot;;print q<#!/usr/local/bin/perl -sw if(!$s){>.($_=<>).q<}else{@s=(q[printf+pop@s,@s],q[#!/usr/local/bin/perl -sw if(!$s){>.(s$%$%%$g,tr=[=[===tr=]=]=||&d,$_).q<}else{@s=(q[%s],q[%s])x2;%s} ])x2;printf+pop@s,@s} >
  4. 4. Beyond syntax
  5. 5. Tools for the toolbox
  6. 6. Easy To Do
  7. 7. Hard To Screw Up
  8. 8. Independent
  9. 9. You can do them alone
  10. 10. Computer Science + People = Software Development
  11. 11. Why learn?
  12. 12. Cross-training is sexay
  13. 13. know
  14. 14. Don’t know
  15. 15. Don’t know you don’t know
  16. 16. “I don’t know”
  17. 17. “Tell me about it”
  18. 18. Why
  19. 19. New things mean failure
  20. 20. New versions
  21. 21. Hang out with other folks who learn
  22. 22. Join the community
  23. 23. Broadcast your problem
  24. 24. Go be stupid
  25. 25. Learn a really different language
  26. 26. Look it up yourself
  27. 27. Wikipedia
  28. 28. Relevant blogs
  29. 29. Tech-specific search sites
  30. 30. > Thank you for your note. Opera is > not a supported browser.
  31. 31. Why not? I see absolutely no reason to exclude Opera from the list of supported browsers. When I tell Opera to ID as Firefox, it works as expected. No patches needed. So please get back in sync with the real world and also enable Opera.
  32. 32. Topic for #eve is: Corp meeting on Vent: Saturday 14th and 21st at 16:00 EVE time. All hands on deck! :-)
  33. 33. <wibble> Announcing quot;all hands on deckquot; without announcing *why* is not useful. <wibble> I get enough shit from work, I certainly don't need any more from a corp on Eve. <wibble> just irritated at people telling me what I *have* to do.
  34. 34. On Wed, May 09, 2007 at 08:34:52PM -0700, Michael G Schwern wrote: > I'm sorry, but that's the automated failure report from CPAN::Reporter. > I was doing an automated install.
  35. 35. What can I do to force automated junk mailers to follow my policy of bug reports?
  36. 36. Speak with the CPAN::Reporter folks about what you would like to see in the failed install report. Perhaps they can add in the Makefile.PL and make output to the automatic report. This would be helpful, especially for complicated builds like yours. Perhaps you could change your test files so they automatically output the diagnostics you want on failure rather than rely on the user to sift through the INSTALL docs to find the special instructions
  37. 37. “You’re right”
  38. 38. someone screwed up the plan in one of Encode's tests.
  39. 39. +1 0 -1
  40. 40. Bitching is not doing
  41. 41. Means
  42. 42. Ends
  43. 43. Be Available
  44. 44. Design <-> Code
  45. 45. Interface -> User
  46. 46. Get it out of your head
  47. 47. Documentation
  48. 48. Wiki
  49. 49. Tickets
  50. 50. How are you?
  51. 51. Having fun?
  52. 52. Feel ok?
  53. 53. Fear-based Programming
  54. 54. Fear of change
  55. 55. Fear of bugs
  56. 56. Fear of getting fired
  57. 57. Small Chunks
  58. 58. Testing
  59. 59. Test first
  60. 60. Test during
  61. 61. Test automaticly
  62. 62. Stay at 100%
  63. 63. Effective Version Control
  64. 64. Code
  65. 65. Test
  66. 66. Commit
  67. 67. How much?
  68. 68. One Thing
  69. 69. One Source Of Breakage
  70. 70. ---------------------------------------------------------------------- r32185: schwern | 2007-06-29 18:22:55 -0700 Need a blank line preceeding POD directives. ---------------------------------------------------------------------- === local/Test-Simple/lib/Test/Builder.pm ================================================================== --- local/Test-Simple/lib/Test/Builder.pm (revision 32184) +++ local/Test-Simple/lib/Test/Builder.pm (revision 32185) @@ -983,6 +983,7 @@ # I'm not ready to publish this. It doesn't deal with array return # values from the code or context. + =begin private =item B<_try>
  71. 71. ---------------------------------------------------------------------- r27706: schwern | 2007-03-16 15:19:55 -0700 Add a test to ensure an object can lie about being an IO::Handle. ---------------------------------------------------------------------- === local/Test-Simple/t/is_fh.t ================================================================== --- local/Test-Simple/t/is_fh.t (revision 27705) +++ local/Test-Simple/t/is_fh.t (revision 27706) @@ -11,7 +11,7 @@ } use strict; -use Test::More tests => 10; +use Test::More tests => 11; use TieOut; ok( !Test::Builder->is_fh(quot;fooquot;), 'string is not a filehandle' ); @@ -34,3 +34,15 @@ unless defined *OUT{IO}; ok( Test::Builder->is_fh(*OUT{IO}) ); } + + +package Lying::isa; + +sub isa { + my $self = shift; + my $parent = shift; + + return 1 if $parent eq 'IO::Handle'; +} + +::ok( Test::Builder->is_fh(bless {}, quot;Lying::isaquot;));
  72. 72. ---------------------------------------------------------------------- r27705: schwern | 2007-03-16 15:10:39 -0700 Comment about the nature of the filehandle in is_fh() was backwards. ---------------------------------------------------------------------- === local/Test-Simple/lib/Test/Builder.pm ================================================================== --- local/Test-Simple/lib/Test/Builder.pm (revision 27704) +++ local/Test-Simple/lib/Test/Builder.pm (revision 27705) @@ -1025,8 +1025,8 @@ my $maybe_fh = shift; return 0 unless defined $maybe_fh; - return 1 if ref $maybe_fh eq 'GLOB'; # its a glob - return 1 if ref $maybe_fh eq 'GLOB'; # its a glob ref + return 1 if ref $maybe_fh eq 'GLOB'; # its a glob ref + return 1 if ref $maybe_fh eq 'GLOB'; # its a glob return eval { $maybe_fh->isa(quot;IO::Handlequot;) } || # 5.5.4's tied() and can() doesn't like getting undef
  73. 73. ---------------------------------------------------------------------- r26467: schwern | 2006-12-24 12:36:01 -0800 Typo ---------------------------------------------------------------------- === local/Test-Simple/Changes ================================================================== --- local/Test-Simple/Changes (revision 26466) +++ local/Test-Simple/Changes (revision 26467) @@ -1,5 +1,5 @@ 0.66 Sun Dec 3 15:25:45 PST 2006 - - Restore 5.4.5 compatibility (unobe@cpan.org) [rt.cpanorg 20513] + - Restore 5.4.5 compatibility (unobe@cpan.org) [rt.cpan.org 20513] 0.65 Fri Nov 10 10:26:51 CST 2006
  74. 74. ---------------------------------------------------------------------- r17879: schwern | 2006-09-04 01:15:12 -0700 * Made most of the error messages report in the caller's context. [rt.cpan.org #20639] ---------------------------------------------------------------------- === local/Test-Simple/lib/Test/Builder.pm ================================================================== --- local/Test-Simple/lib/Test/Builder.pm (revision 17878) +++ local/Test-Simple/lib/Test/Builder.pm (revision 17879) @@ -35,7 +35,7 @@ $$data = ${$_[0]}; } else { - die quot;Unknown type: quot;.$type; + die(quot;Unknown type: quot;.$type); } $_[0] = &threads::shared::share($_[0]); @@ -50,7 +50,7 @@ ${$_[0]} = $$data; } else { - die quot;Unknown type: quot;.$type; + die(quot;Unknown type: quot;.$type); } return $_[0]; @@ -247,8 +247,7 @@ return unless $cmd; if( $self->{Have_Plan} ) { - die sprintf quot;You tried to plan twice! Second plan at %s line %dnquot;, - ($self->caller)[1,2]; + $self->croak(quot;You tried to plan twicequot;); } ...
  75. 75. Task branches
  76. 76. BDUF
  77. 77. Refactoring
  78. 78. JIT Design
  79. 79. Rename
  80. 80. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $arg = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$argquot;>/; } if ( my $arg = delete $parms{format} ) { if ($arg eq 'text') { require HTML::TreeBuilder; my $tree = HTML::TreeBuilder->new(); $tree->parse($content); $tree->eof(); $tree->elementify(); # just for safety $content = $tree->as_text(); $tree->delete; } else { $self->die( qq{Unknown quot;formatquot; parameter quot;$argquot;} ); } } for my $cmd ( sort keys %parms ) { $self->die( qq{Unknown named argument quot;$cmdquot;} ); } } # is HTML return $content; }
  81. 81. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $arg = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$argquot;>/; } if ( my $arg = delete $parms{format} ) { if ($arg eq 'text') { require HTML::TreeBuilder; my $tree = HTML::TreeBuilder->new(); $tree->parse($content); $tree->eof(); $tree->elementify(); # just for safety $content = $tree->as_text(); $tree->delete; } else { $self->die( qq{Unknown quot;formatquot; parameter quot;$argquot;} ); } } for my $cmd ( sort keys %parms ) { $self->die( qq{Unknown named argument quot;$cmdquot;} ); } } # is HTML return $content; }
  82. 82. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $base_href = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$base_hrefquot;>/; } if ( my $format = delete $parms{format} ) { if ($format eq 'text') { require HTML::TreeBuilder; my $tree = HTML::TreeBuilder->new(); $tree->parse($content); $tree->eof(); $tree->elementify(); # just for safety $content = $tree->as_text(); $tree->delete; } else { $self->die( qq{Unknown quot;formatquot; parameter quot;$formatquot;} ); } } for my $cmd ( sort keys %parms ) { $self->die( qq{Unknown named argument quot;$cmdquot;} ); } } # is HTML return $content; }
  83. 83. Extract
  84. 84. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $base_href = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$base_hrefquot;>/; } if ( my $format = delete $parms{format} ) { if ($format eq 'text') { require HTML::TreeBuilder; my $tree = HTML::TreeBuilder->new(); $tree->parse($content); $tree->eof(); $tree->elementify(); # just for safety $content = $tree->as_text(); $tree->delete; } else { $self->die( qq{Unknown quot;formatquot; parameter quot;$formatquot;} ); } } for my $cmd ( sort keys %parms ) { $self->die( qq{Unknown named argument quot;$cmdquot;} ); } } # is HTML return $content; }
  85. 85. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $base_href = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$base_hrefquot;>/; } if ( my $format = delete $parms{format} ) { if ($format eq 'text') { require HTML::TreeBuilder; my $tree = HTML::TreeBuilder->new(); $tree->parse($content); $tree->eof(); $tree->elementify(); # just for safety $content = $tree->as_text(); $tree->delete; } else { $self->die( qq{Unknown quot;formatquot; parameter quot;$formatquot;} ); } } for my $cmd ( sort keys %parms ) { $self->die( qq{Unknown named argument quot;$cmdquot;} ); } } # is HTML return $content; }
  86. 86. if ( my $format = delete $parms{format} ) { if ($format eq 'text') { require HTML::TreeBuilder; my $tree = HTML::TreeBuilder->new(); $tree->parse($content); $tree->eof(); $tree->elementify(); # just for safety $content = $tree->as_text(); $tree->delete; } else { $self->die( qq{Unknown quot;formatquot; parameter quot;$formatquot;} ); } }
  87. 87. if ( my $format = delete $parms{format} ) { if ($format eq 'text') { require HTML::TreeBuilder; my $tree = HTML::TreeBuilder->new(); $tree->parse($content); $tree->eof(); $tree->elementify(); # just for safety $content = $tree->as_text(); $tree->delete; } else { $self->die( qq{Unknown quot;formatquot; parameter quot;$formatquot;} ); } }
  88. 88. method _content_as_text ($content) { require HTML::TreeBuilder; my $tree = HTML::TreeBuilder->new(); $tree->parse($content); $tree->eof(); $tree->elementify(); # just for safety my $formatted_content = $tree->as_text(); $tree->delete; return $formatted_content; }
  89. 89. if ( my $format = delete $parms{format} ) { if ($format eq 'text') { $content = $self->_content_as_text($content); } else { $self->die( qq{Unknown quot;formatquot; parameter quot;$formatquot;} ); } }
  90. 90. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $base_href = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$base_hrefquot;>/; } if ( my $format = delete $parms{format} ) { if ($format eq 'text') { require HTML::TreeBuilder; my $tree = HTML::TreeBuilder->new(); $tree->parse($content); $tree->eof(); $tree->elementify(); # just for safety $content = $tree->as_text(); $tree->delete; } else { $self->die( qq{Unknown quot;formatquot; parameter quot;$formatquot;} ); } } for my $cmd ( sort keys %parms ) { $self->die( qq{Unknown named argument quot;$cmdquot;} ); } } # is HTML return $content; }
  91. 91. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $base_href = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$base_hrefquot;>/; } if ( my $format = delete $parms{format} ) { if ($format eq 'text') { $content = $self->_content_as_text($content); } else { $self->die( qq{Unknown quot;formatquot; parameter quot;$formatquot;} ); } } for my $cmd ( sort keys %parms ) { $self->die( qq{Unknown named argument quot;$cmdquot;} ); } } # is HTML return $content; }
  92. 92. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $base_href = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$base_hrefquot;>/; } if ( my $format = delete $parms{format} ) { if ($format eq 'text') { $content = $self->_content_as_text($content); } else { $self->die( qq{Unknown quot;formatquot; parameter quot;$formatquot;} ); } } for my $cmd ( sort keys %parms ) { $self->die( qq{Unknown named argument quot;$cmdquot;} ); } } # is HTML return $content; }
  93. 93. method _format_content ($format, $content) { if ($format eq 'text') { return $self->_content_as_text($content); } else { $self->die( qq{Unknown quot;formatquot; parameter quot;$formatquot;} ); } }
  94. 94. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $base_href = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$base_hrefquot;>/; } if ( my $format = delete $parms{format} ) { if ($format eq 'text') { $content = $self->_content_as_text($content); } else { $self->die( qq{Unknown quot;formatquot; parameter quot;$formatquot;} ); } } for my $cmd ( sort keys %parms ) { $self->die( qq{Unknown named argument quot;$cmdquot;} ); } } # is HTML return $content; }
  95. 95. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $base_href = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$base_hrefquot;>/; } if ( my $format = delete $parms{format} ) { $content = $self->_format_content($format, $content); } for my $cmd ( sort keys %parms ) { $self->die( qq{Unknown named argument quot;$cmdquot;} ); } } # is HTML return $content; }
  96. 96. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $base_href = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$base_hrefquot;>/; } if ( my $format = delete $parms{format} ) { $content = $self->_format_content($format, $content); } for my $cmd ( sort keys %parms ) { $self->die( qq{Unknown named argument quot;$cmdquot;} ); } } # is HTML return $content; }
  97. 97. method _check_unhandled_parms (%parms) { for my $cmd ( sort keys %parms ) { $self->die( qq{Unknown named argument quot;$cmdquot;} ); } }
  98. 98. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $base_href = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$base_hrefquot;>/; } if ( my $format = delete $parms{format} ) { $content = $self->_format_content($format, $content); } for my $cmd ( sort keys %parms ) { $self->die( qq{Unknown named argument quot;$cmdquot;} ); } } # is HTML return $content; }
  99. 99. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $base_href = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$base_hrefquot;>/; } if ( my $format = delete $parms{format} ) { $content = $self->_format_content($format, $content); } $self->_check_unhandled_parms(%parms); } # is HTML return $content; }
  100. 100. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $base_href = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$base_hrefquot;>/; } if ( my $format = delete $parms{format} ) { $content = $self->_format_content($format, $content); } $self->_check_unhandled_parms(%parms); } # is HTML return $content; }
  101. 101. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $base_href = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$base_hrefquot;>/; } if ( my $format = delete $parms{format} ) { $content = $self->_format_content($format, $content); } $self->_check_unhandled_parms(%parms); } return $content; }
  102. 102. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $base_href = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$base_hrefquot;>/; } if ( my $format = delete $parms{format} ) { if ($format eq 'text') { require HTML::TreeBuilder; my $tree = HTML::TreeBuilder->new(); $tree->parse($content); $tree->eof(); $tree->elementify(); # just for safety $content = $tree->as_text(); $tree->delete; } else { $self->die( qq{Unknown quot;formatquot; parameter quot;$formatquot;} ); } } for my $cmd ( sort keys %parms ) { $self->die( qq{Unknown named argument quot;$cmdquot;} ); } } # is HTML return $content; }
  103. 103. method content () { my $content = $self->{content}; if ( $self->is_html ) { my %parms = @_; if ( exists $parms{base_href} ) { my $base_href = (delete $parms{base_href}) || $self->base; $content =~ s/<head>/<head>n<base href=quot;$base_hrefquot;>/; } if ( my $format = delete $parms{format} ) { $content = $self->_format_content($format, $content); } $self->_check_unhandled_parms(%parms); } return $content; }
  104. 104. Revealing Reuse
  105. 105. refactoring.com
  106. 106. Simplest Thing
  107. 107. Optimizing
  108. 108. Rule #1
  109. 109. Rule #1: Don’t!
  110. 110. Complicates
  111. 111. Wastes Time
  112. 112. Rule #2
  113. 113. Rule #2: Don’t do it yet!
  114. 114. Does it work?
  115. 115. Is it tested?
  116. 116. Is it documented?
  117. 117. How fast?
  118. 118. Throw Hardware
  119. 119. Rule #3
  120. 120. Rule #3: Profile First!
  121. 121. Rule #4
  122. 122. Rule #4: Better Algorithm
  123. 123. Rule #5
  124. 124. Estimating
  125. 125. Feedback
  126. 126. Mini Milestones
  127. 127. • Get account activated • Make simple test purchase • Handle invalid expiration date • Handle invalid address • Record transactions • Associate item with purchase • Simple user form
  128. 128. Quatloos
  129. 129. Get Out Of Technical Debt NOW!
  130. 130. Form
  131. 131. Functionality
  132. 132. Separate
  133. 133. People
  134. 134. Small Chunky Pieces
  135. 135. Thank You
  136. 136. Gabrielle
  137. 137. Candy
  138. 138. Selena
  139. 139. Keith
  140. 140. Everyone I pestered
  141. 141. Discussion Session D135 @ 5:30pm

×