Slide 1

Slide 1 text

Refactoring and Readability Southeast Linuxfest
 
 2019-06-14

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Refactoring and Readability http://speakerdeck.com/util
 
 <<< >>> >>> <<<

Slide 4

Slide 4 text

OK, so we're doing this...
 


Slide 5

Slide 5 text

OK, so we're doing this...
 -- Aaron Burr


Slide 6

Slide 6 text

OK, so we're doing this...
 -- Aaron Burr
 (Also)

Slide 7

Slide 7 text

OK, so we're doing this...
 -- Aaron Burr
 -- Brock Sampson

Slide 8

Slide 8 text

( This space intentionally left blank )

Slide 9

Slide 9 text

Refactoring and Readability http://speakerdeck.com/util
 
 <<< >>> >>> <<<

Slide 10

Slide 10 text

Pump Up…

Slide 11

Slide 11 text

Q&A ⅔

Slide 12

Slide 12 text

/me

Slide 13

Slide 13 text

Util

Slide 14

Slide 14 text

RosettaCode:
 where Perl 6 goes to
 Flex Shine

Slide 15

Slide 15 text

CodeFights 40 languages

Slide 16

Slide 16 text

Assume Modern

Slide 17

Slide 17 text

sub foo { die if @_ != 3; my ($x, $y, $z) = @_; ⋮ }

Slide 18

Slide 18 text

# Assume all my Perl 5 code begins with: use strict; use warnings; use 5.020; use experimental qw;

Slide 19

Slide 19 text

use strict; use warnings; use 5.020; use experimental qw; sub foo ( $x, $y, $z ) { ⋮

Slide 20

Slide 20 text

use strict; use warnings; use 5.020; use experimental qw; sub foo ( $x, $y, $z ) { ⋮

Slide 21

Slide 21 text

sub foo ( $x, $y, $z ) { ⋮

Slide 22

Slide 22 text

last;

Slide 23

Slide 23 text

Refactoring

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

Refactoring Safely

Slide 26

Slide 26 text

Refactoring Sanely

Slide 27

Slide 27 text

git init
 git add .
 git commit -m 'Initial commit'

Slide 28

Slide 28 text

sqlite + cUrl + perl + md5

Slide 29

Slide 29 text

Modes Fix Add Refactor

Slide 30

Slide 30 text


 Forces Surrounding Code Code Easy to write Standard form Ease of change Easy to read Performance (Speed) Boundaries of Responsibility (Slicing)

Slide 31

Slide 31 text


 Forces Surrounding Code Code Easy to write Standard form Ease of change Easy to read Performance (Speed) Boundaries of Responsibility

Slide 32

Slide 32 text

Mechanics

Slide 33

Slide 33 text

sub final_form ($fighter) { ... code ... }

Slide 34

Slide 34 text

sub trigger_final_form ($fighter) { ... code ... }

Slide 35

Slide 35 text

sub final_form ($fighter) { return trigger_final_form($fighter); } sub trigger_final_form ($fighter) { ... code ... }

Slide 36

Slide 36 text

sub trigger_final_form ($fighter) { ... code ... }

Slide 37

Slide 37 text

Refactor to Debug:
 Wrapping

Slide 38

Slide 38 text

sub should_log ( $department ) { my $r; if ( $audits{$department} ) { $r = 1 } elsif ( $department eq 'IA' ) { $r = 1 } else { $r = 0 } return $r; }

Slide 39

Slide 39 text

sub should_log ( $department ) { return 1 if $audits{$department}; return 1 if $department eq 'IA'; return 0; }

Slide 40

Slide 40 text

sub should_log ( $department ) { return 1 if $audits{$department}; return 1 if $department eq 'IA'; return 0; }

Slide 41

Slide 41 text

sub should_log_WRAPPED ( $department ) { return 1 if $audits{$department}; return 1 if $department eq 'IA'; return 0; }

Slide 42

Slide 42 text

sub should_log_WRAPPED ( $department ) { return 1 if $audits{$department}; return 1 if $department eq 'IA'; return 0; } sub should_log ( $department ) { my $r = should_log_WRAPPED($department); return $r;

Slide 43

Slide 43 text

sub should_log_WRAPPED ( $department ) { return 1 if $audits{$department}; return 1 if $department eq 'IA'; return 0; } sub should_log ( $department ) { say "> should_log:", Dumper $department; my $r = should_log_WRAPPED($department); say "< should_log:", Dumper $r; return $r;

Slide 44

Slide 44 text

sub should_log_WRAPPED ( $department ) { return 1 if $audits{$department}; return 1 if $department eq 'IA'; return 0; } sub should_log ( $department ) { my $r = should_log_WRAPPED($department); return $r; perl -d pgm c should_log n p $department n p $r $r = 0 c

Slide 45

Slide 45 text


 Forces Surrounding Code Code Easy to write Standard form Ease of change Easy to read Performance (Speed) Boundaries of Responsibility

Slide 46

Slide 46 text


 Forces Surrounding Code Code Easy to write Standard form Ease of change Easy to read Performance (Speed) Boundaries of Responsibility

Slide 47

Slide 47 text

Rules Of Optimization wiki.c2.com First Rule Of Optimization - Don't. Second Rule Of Optimization - Don't... yet. Profile Before Optimizing

Slide 48

Slide 48 text

That's another show...

Slide 49

Slide 49 text


 Forces Surrounding Code Code Easy to write Standard form Ease of change Easy to read Performance (Speed) Boundaries of Responsibility

Slide 50

Slide 50 text

Readability

Slide 51

Slide 51 text

Readability

Slide 52

Slide 52 text

Wholesale (changes)

Slide 53

Slide 53 text

print_machine( $machine, $format, $start ); reset_machine( $machine, $init_value ); confuse_machine( $machine, $level, $ray ); print_register( $register ); reset_register( $register ); amend_register( $register, $new_value );

Slide 54

Slide 54 text

print_machine( $machine, $format, $start ); reset_machine( $machine, $init_value ); confuse_machine( $machine, $level, $ray ); print_register( $register ); reset_register( $register ); amend_register( $register, $new_value );

Slide 55

Slide 55 text

print_machine( $machine, $format, $start ); reset_machine( $machine, $init_value ); confuse_machine( $machine, $level, $ray ); print_register( $register ); reset_register( $register ); amend_register( $register, $new_value );

Slide 56

Slide 56 text

print_machine( $machine, $format, $start ); reset_machine( $machine, $init_value ); confuse_machine( $machine, $level, $ray ); print_register( $register ); reset_register( $register ); amend_register( $register, $new_value );

Slide 57

Slide 57 text

$machine->print( $format, $start ); $machine->reset( $init_value ); $machine->confuse( $level, $ray ); $register->print( $register ); $register->reset( $register ); $register->amend( $register, $new_value );

Slide 58

Slide 58 text

print_machine( $machine, $format, $start ); reset_machine( $machine, $init_value ); confuse_machine( $machine, $level, $ray ); print_register( $register ); reset_register( $register ); amend_register( $register, $new_value );

Slide 59

Slide 59 text

print_machine( $machine, $format, $start );

Slide 60

Slide 60 text

print_machine( $machine, $format, $start );

Slide 61

Slide 61 text

print_machine( $machine, $format, $start ); $machine->print( $format, $start );

Slide 62

Slide 62 text

Dense

Slide 63

Slide 63 text

for my $car (@vehicles) { my $color = $colors_by_type[ $car->type ]; if ( not $color->available ) { $color = $colors_by_type[ rand @colors_by_type ]; } $car->assemble_inspect_and_ship($color); $dealers[ $car->order_source ]++; }

Slide 64

Slide 64 text

for my $car (@vehicles) { my $color = get_car_color(@car); $car->assemble_paint_and_ship($color); $dealers->give_credit_for_order($car); }

Slide 65

Slide 65 text

Wow!

Slide 66

Slide 66 text

def factorial(n): n0 = 1 n1 = 1 n2 = 2 n3 = 6 n4 = 24 n5 = 120 n6 = 720 n7 = 5040 n8 = 40320 n9 = 362880 n10 = 3628800 n11 = 39916800 n12 = 479001600 n13 = 6227020800 n14 = 87178291200 n15 = 1307674368000 if n == 0: return n0 elif n == 1: return n1 elif n == 2: return n2 elif n == 3: return n3 elif n == 4: return n4 elif n == 5: return n5 elif n == 6: return n6 elif n == 7: return n7 elif n == 8: return n8 elif n == 9: return n9 elif n == 10: return n10 elif n == 11: return n11 elif n == 12: return n12 elif n == 13: return n13 elif n == 14: return n14 elif n == 15: return n15

Slide 67

Slide 67 text

def factorial(n): n0 = 1 n1 = 1 n2 = 2 n3 = 6 n4 = 24 n5 = 120 n6 = 720 n7 = 5040 n8 = 40320 n9 = 362880 n10 = 3628800 n11 = 39916800 n12 = 479001600 n13 = 6227020800 n14 = 87178291200 n15 = 1307674368000 if n == 0: return n0 elif n == 1: return n1 elif n == 2: return n2 elif n == 3: return n3 elif n == 4: return n4 elif n == 5: return n5 elif n == 6: return n6 elif n == 7: return n7 elif n == 8: return n8 elif n == 9: return n9 elif n == 10: return n10 elif n == 11: return n11 elif n == 12: return n12 elif n == 13: return n13 elif n == 14: return n14 elif n == 15: return n15

Slide 68

Slide 68 text

def factorial(n): if n == 0: return 1 elif n == 1: return 1 elif n == 2: return 2 elif n == 3: return 6 elif n == 4: return 24 elif n == 5: return 120 elif n == 6: return 720 elif n == 7: return 5040 elif n == 8: return 40320 elif n == 9: return 362880 elif n == 10: return 3628800 elif n == 11: return 39916800 elif n == 12: return 479001600 elif n == 13: return 6227020800 elif n == 14: return 87178291200 elif n == 15: return 1307674368000

Slide 69

Slide 69 text

def factorial(n): fact = [ 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000] return fact[n]

Slide 70

Slide 70 text

def factorial(n): f = 1 for x in range(2, n+1): f *= x return f

Slide 71

Slide 71 text

@factorials = 1, |[\*] 1 .. *; # Perl 6

Slide 72

Slide 72 text

@factorials = 1, |[\*] 1 .. *; # Perl 6 fact = [1] # Caches between calls! def factorial(n): while len(fact)-1 < n: fact.append( fact[-1] * len(fact) ) return fact[n]

Slide 73

Slide 73 text

def factorial(n): f = 1 for x in range(2, n+1): f *= x return f

Slide 74

Slide 74 text

import math factorial = math.factorial

Slide 75

Slide 75 text

Can't miss

Slide 76

Slide 76 text

http://www.smbc-comics.com/comic/2010-11-26

Slide 77

Slide 77 text

Enter the Matrix Final Chapter

Slide 78

Slide 78 text

foo(); bar(); foo(); bar(); foo(); bar(); foo(); bar();

Slide 79

Slide 79 text

for (1 .. 4) { foo(); bar(); }

Slide 80

Slide 80 text

31w + 55x + 46y + 30z = 76 84w + 92x + 37y + 72z = 16 57w + 37x + 34y + 85z = 71 93w + 62x + 71y + 49z = 42 86w + 48x + 36y + 42z = 88 -34w + 71x + 47y + 32z = 73 21w + 32x + 34y + 19z = 54 -99w + 25x + 39y + 62z = 23

Slide 81

Slide 81 text

[ 1, 0, 0, 0, 31, 55, 46, 30, 76 ], [ 0, 1, 0, 0, 84, 92, 37, 72, 16 ], [ 0, 0, 1, 0, 57, 37, 34, 85, 71 ], [ 0, 0, 0, 1, 93, 62, 71, 49, 42 ], [ 0, 0, 0, 0, 86, 48, 36, 42, 88 ], [ 0, 0, 0, 0, -34, 71, 47, 32, 73 ], [ 0, 0, 0, 0, 21, 32, 34, 19, 54 ], [ 0, 0, 0, 0, -99, 25, 39, 62, 23 ],

Slide 82

Slide 82 text

[ 1, 0, 0, 0, 31, 55, 46, 30, 76 ], [ 0, 1, 0, 0, 84, 92, 37, 72, 16 ], [ 0, 0, 1, 0, 57, 37, 34, 85, 71 ], [ 0, 0, 0, 1, 93, 62, 71, 49, 42 ], [ 0, 0, 0, 0, 86, 48, 36, 42, 88 ], [ 0, 0, 0, 0, -34, 71, 47, 32, 73 ], [ 0, 0, 0, 0, 21, 32, 34, 19, 54 ], [ 0, 0, 0, 0, -99, 25, 39, 62, 23 ],

Slide 83

Slide 83 text

[ 1, 0, 0, 0, 31, 55, 46, 30, 76 ], [ 0, 1, 0, 0, 84, 92, 37, 72, 16 ], [ 0, 0, 1, 0, 57, 37, 34, 85, 71 ], [ 0, 0, 0, 1, 93, 62, 71, 49, 42 ], [ 0, 0, 0, 0, 86, 48, 36, 42, 88 ], [ 0, 0, 0, 0, -34, 71, 47, 32, 73 ], [ 0, 0, 0, 0, 21, 32, 34, 19, 54 ], [ 0, 0, 0, 0, -99, 25, 39, 62, 23 ],

Slide 84

Slide 84 text

def gauss(m): n, p = len(m), len(m[0]) for i in range(n): k = i + argmax(m[i:n],i) m[i], m[k] = m[k], m[i] ⋮

Slide 85

Slide 85 text

k = i + argmax( m[i:n], i )

Slide 86

Slide 86 text

def argmax(m,i): col = [abs(row[i]) for row in m] return col.index(max(col))

Slide 87

Slide 87 text

def argmax(m,i): col = [abs(row[i]) for row in m] return col.index(max(col))

Slide 88

Slide 88 text

def argmax(m,i): col = [abs(row[i]) for row in m] return col.index(max(col)) # Double work!

Slide 89

Slide 89 text

# Perl 5 use List::UtilsBy qw; $tallest = max_by { $_->height } @people; # Perl 6 $tallest = @people.max( *.height ); # Python (since 2.5 in 2006) tallest = max(people, key=lambda x: x.height);

Slide 90

Slide 90 text

max( range(i, n), key = lambda x: abs(m[x][i]) )

Slide 91

Slide 91 text

max( range(i, n), key = lambda x: abs(m[x][i]) )

Slide 92

Slide 92 text

k = i + argmax( m[i:n], i ) k = max(range(i, n), key = lambda x: abs(m[x][i]))

Slide 93

Slide 93 text

k = i + argmax( m[i:n], i ) k = max(range(i, n), key = lambda x: abs(m[x][i])) $k = max_by { abs($m[$_][$i]) } $i..$#m; #P5

Slide 94

Slide 94 text

def column_index_with_max_abs_value(m,i): return max(range(i, n), key = lambda x: abs(m[x][i])) k = column_index_with_max_abs_value(m,i)

Slide 95

Slide 95 text

Perl 6 == 
 Perl 5 minus Warts plus Awesome

Slide 96

Slide 96 text

Thanks!

Slide 97

Slide 97 text

Key knowledge (Perl) • List::Util first max min sum all any none uniq shuffle • List::UtilsBy max_by min_by count_by • perlfunc Perl Functions by Category • Test::Tutorial Intro to Automated Testing • Devel::Cover Shows code that lacks testing • Benchmark Performance comparisons • Devel::NYTProf Perfomance profiler

Slide 98

Slide 98 text

Copyrights

Slide 99

Slide 99 text

Copyright Information: Images • Camelia • (c) 2009 by Larry Wall
 http://github.com/perl6/mu/raw/master/misc/ camelia.txt • New rules for Science Journalism • Zach Weinersmith
 http://www.smbc-comics.com/comic/ 2010-11-26 • Packages • © Randall Munroe
 https://xkcd.com/576/


Slide 100

Slide 100 text

Copyright Information: This Talk This work is licensed under a Creative Commons Attribution 4.0 International License. CC BY https://creativecommons.org/licenses/by/4.0/

Slide 101

Slide 101 text

Links • The original book, for Java. Now also for Ruby and JS
 https://refactoring.com/ • Book: Refactoring JavaScript
 http://refactoringjs.com/ • http://wiki.c2.com/?RulesOfOptimization • http://wiki.c2.com/?ProfileBeforeOptimizing

Slide 102

Slide 102 text

History • v 0.99 2019-06-06
 Presented at Atlanta Perlmongers (shelved) • v 1.01 2019-06-14
 Presented at Southeast LinuxFest