Click here to load reader
Jun 11, 2015
/;{}def/#{def}def/$_={/TimesBoldexchselectfont}#/_{ rmoveto} #/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup260 40 moveto 90 rotate ; %/}};$0='"\e[7m \e[0m"';@ARGV=split//,reverseq(ThePerl). q(Journal) x 220 ; q ; 0 T putinterval exch 7 J putinterval ; ; $_= q /m$ pop T($*!$"=!$ " )pop " * true% ? $ " $!" " !! !! % !" !" !! charpath {!"""}pop $ pop{""!}pop ! neg{!#}pop 220 ! neg _{!!}pop J false %Tcharpath clip " pop 0 " moveto 6{!!}pop $_= 105{!!}pop {$ ! $ " ! #! ##}pop{dup dup $ ! " pop pop q{"}pop 22{dup show}repeat {"}pop q 22 mul{$ "} popneg{!#! $ "}pop ! 8 .65 mul{$ # # $}pop ! neg{"}pop _ pop{"}pop } repeat pop" { $ " ! ! ! $ " ! !" "#" #"!"""""! #" " # "m/;@ARGV=(@ARGV[14..1])x50;q} 0 "%};s/m[ou]|[\dAlnz.\n_{}]|\$_=//gx;s/(.)(?{$*=''})/('$*.='.(++$#%2?'':"$0;").'pop;')x(ord($1)31).'$*'/gee;s/((.(\e\[.m)*|.){77})/$1\n/g;print; sub showpage {}@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print#:: ::| ::| .. :||:: 0| .| ::||| .:|. :||open(Q,$0);while(<Q>){if(/^#(.*)$/){for(split('',$1)){$q=0;for(split){s/\|/:.:/xg;s/:/../g;$Q=$_?length:$_;$q+=$q?$Q:$Q*20;}print chr($q);}}}print"\n";#.: ::||| .||| :|||| ::||| ||:: :|||| .:|/;{}def/#{def}def/$_={/TimesBold exch selectfont}#/_{rmoveto}#/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup
Readable Perl
GeekUp Liverpool, Tuesday 27th May, 2008http://upcoming.yahoo.com/event/691199/
/;{}def/#{def}def/$_={/TimesBoldexchselectfont}#/_{ rmoveto} #/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup260 40 moveto 90 rotate ; %/}};$0='"\e[7m \e[0m"';@ARGV=split//,reverseq(ThePerl). q(Journal) x 220 ; q ; 0 T putinterval exch 7 J putinterval ; ; $_= q /m$ pop T($*!$"=!$ " )pop " * true% ? $ " $!" " !! !! % !" !" !! charpath {!"""}pop $ pop{""!}pop ! neg{!#}pop 220 ! neg _{!!}pop J false %Tcharpath clip " pop 0 " moveto 6{!!}pop $_= 105{!!}pop {$ ! $ " ! #! ##}pop{dup dup $ ! " pop pop q{"}pop 22{dup show}repeat {"}pop q 22 mul{$ "} popneg{!#! $ "}pop ! 8 .65 mul{$ # # $}pop ! neg{"}pop _ pop{"}pop } repeat pop" { $ " ! ! ! $ " ! !" "#" #"!"""""! #" " # "m/;@ARGV=(@ARGV[14..1])x50;q} 0 "%};s/m[ou]|[\dAlnz.\n_{}]|\$_=//gx;s/(.)(?{$*=''})/('$*.='.(++$#%2?'':"$0;").'pop;')x(ord($1)31).'$*'/gee;s/((.(\e\[.m)*|.){77})/$1\n/g;print; sub showpage {}@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print#:: ::| ::| .. :||:: 0| .| ::||| .:|. :||open(Q,$0);while(<Q>){if(/^#(.*)$/){for(split('',$1)){$q=0;for(split){s/\|/:.:/xg;s/:/../g;$Q=$_?length:$_;$q+=$q?$Q:$Q*20;}print chr($q);}}}print"\n";#.: ::||| .||| :|||| ::||| ||:: :|||| .:|/;{}def/#{def}def/$_={/TimesBold exch selectfont}#/_{rmoveto}#/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup
It's possible for Perl programmers
to write messy programs.
/;{}def/#{def}def/$_={/TimesBoldexchselectfont}#/_{ rmoveto} #/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup260 40 moveto 90 rotate ; %/}};$0='"\e[7m \e[0m"';@ARGV=split//,reverseq(ThePerl). q(Journal) x 220 ; q ; 0 T putinterval exch 7 J putinterval ; ; $_= q /m$ pop T($*!$"=!$ " )pop " * true% ? $ " $!" " !! !! % !" !" !! charpath {!"""}pop $ pop{""!}pop ! neg{!#}pop 220 ! neg _{!!}pop J false %Tcharpath clip " pop 0 " moveto 6{!!}pop $_= 105{!!}pop {$ ! $ " ! #! ##}pop{dup dup $ ! " pop pop q{"}pop 22{dup show}repeat {"}pop q 22 mul{$ "} popneg{!#! $ "}pop ! 8 .65 mul{$ # # $}pop ! neg{"}pop _ pop{"}pop } repeat pop" { $ " ! ! ! $ " ! !" "#" #"!"""""! #" " # "m/;@ARGV=(@ARGV[14..1])x50;q} 0 "%};s/m[ou]|[\dAlnz.\n_{}]|\$_=//gx;s/(.)(?{$*=''})/('$*.='.(++$#%2?'':"$0;").'pop;')x(ord($1)31).'$*'/gee;s/((.(\e\[.m)*|.){77})/$1\n/g;print; sub showpage {}@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print#:: ::| ::| .. :||:: 0| .| ::||| .:|. :||open(Q,$0);while(<Q>){if(/^#(.*)$/){for(split('',$1)){$q=0;for(split){s/\|/:.:/xg;s/:/../g;$Q=$_?length:$_;$q+=$q?$Q:$Q*20;}print chr($q);}}}print"\n";#.: ::||| .||| :|||| ::||| ||:: :|||| .:|/;{}def/#{def}def/$_={/TimesBold exch selectfont}#/_{rmoveto}#/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup
It's possible for Perl programmers
to write messy programs.
In case you hadn't
noticed.
/;{}def/#{def}def/$_={/TimesBoldexchselectfont}#/_{ rmoveto} #/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup260 40 moveto 90 rotate ; %/}};$0='"\e[7m \e[0m"';@ARGV=split//,reverseq(ThePerl). q(Journal) x 220 ; q ; 0 T putinterval exch 7 J putinterval ; ; $_= q /m$ pop T($*!$"=!$ " )pop " * true% ? $ " $!" " !! !! % !" !" !! charpath {!"""}pop $ pop{""!}pop ! neg{!#}pop 220 ! neg _{!!}pop J false %Tcharpath clip " pop 0 " moveto 6{!!}pop $_= 105{!!}pop {$ ! $ " ! #! ##}pop{dup dup $ ! " pop pop q{"}pop 22{dup show}repeat {"}pop q 22 mul{$ "} popneg{!#! $ "}pop ! 8 .65 mul{$ # # $}pop ! neg{"}pop _ pop{"}pop } repeat pop" { $ " ! ! ! $ " ! !" "#" #"!"""""! #" " # "m/;@ARGV=(@ARGV[14..1])x50;q} 0 "%};s/m[ou]|[\dAlnz.\n_{}]|\$_=//gx;s/(.)(?{$*=''})/('$*.='.(++$#%2?'':"$0;").'pop;')x(ord($1)31).'$*'/gee;s/((.(\e\[.m)*|.){77})/$1\n/g;print; sub showpage {}@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print#:: ::| ::| .. :||:: 0| .| ::||| .:|. :||open(Q,$0);while(<Q>){if(/^#(.*)$/){for(split('',$1)){$q=0;for(split){s/\|/:.:/xg;s/:/../g;$Q=$_?length:$_;$q+=$q?$Q:$Q*20;}print chr($q);}}}print"\n";#.: ::||| .||| :|||| ::||| ||:: :|||| .:|/;{}def/#{def}def/$_={/TimesBold exch selectfont}#/_{rmoveto}#/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup
It's possible for the programmer to make a mess of things.
It's possible for Perl programmers to write messy programs.
(In case you hadn't noticed.) It's also possible for Perl
programmers to write extremely clean, concise, and beautiful programs.
The very fact that it's possible to write messy programs in Perl is also whatmakes it possible to write programs
that are cleaner in Perl than they could ever be in a language that attempts to enforce cleanliness.
Larry Wall
/;{}def/#{def}def/$_={/TimesBoldexchselectfont}#/_{ rmoveto} #/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup260 40 moveto 90 rotate ; %/}};$0='"\e[7m \e[0m"';@ARGV=split//,reverseq(ThePerl). q(Journal) x 220 ; q ; 0 T putinterval exch 7 J putinterval ; ; $_= q /m$ pop T($*!$"=!$ " )pop " * true% ? $ " $!" " !! !! % !" !" !! charpath {!"""}pop $ pop{""!}pop ! neg{!#}pop 220 ! neg _{!!}pop J false %Tcharpath clip " pop 0 " moveto 6{!!}pop $_= 105{!!}pop {$ ! $ " ! #! ##}pop{dup dup $ ! " pop pop q{"}pop 22{dup show}repeat {"}pop q 22 mul{$ "} popneg{!#! $ "}pop ! 8 .65 mul{$ # # $}pop ! neg{"}pop _ pop{"}pop } repeat pop" { $ " ! ! ! $ " ! !" "#" #"!"""""! #" " # "m/;@ARGV=(@ARGV[14..1])x50;q} 0 "%};s/m[ou]|[\dAlnz.\n_{}]|\$_=//gx;s/(.)(?{$*=''})/('$*.='.(++$#%2?'':"$0;").'pop;')x(ord($1)31).'$*'/gee;s/((.(\e\[.m)*|.){77})/$1\n/g;print; sub showpage {}@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print#:: ::| ::| .. :||:: 0| .| ::||| .:|. :||open(Q,$0);while(<Q>){if(/^#(.*)$/){for(split('',$1)){$q=0;for(split){s/\|/:.:/xg;s/:/../g;$Q=$_?length:$_;$q+=$q?$Q:$Q*20;}print chr($q);}}}print"\n";#.: ::||| .||| :|||| ::||| ||:: :|||| .:|/;{}def/#{def}def/$_={/TimesBold exch selectfont}#/_{rmoveto}#/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup
It's possible for the programmer to make a mess of things.
It's possible for Perl programmers to write messy programs.
(In case you hadn't noticed.) It's also possible for Perl
programmers to write extremely clean, concise, and beautiful programs.
The very fact that it's possible to write messy programs in Perl is also whatmakes it possible to write programs
that are cleaner in Perl than they could ever be in a language that attempts to enforce cleanliness.
Larry Wall
Disclaimer
<<Your favourite language>> is probably very nice too
Every language makes different tradeoffs with readability
This is (mainly) about Perl's
&$%@!
Sigils...
Hungarian Notation
$one
@many
%dictionary
Constructing Strings
In a VBlike syntax "First: " + first + " Last: " + last + vbCrLf + "Age: " + age
Constructing Strings
In Perl, with interpolation "First: $first Last: $last\nAge: $age"
Constructing Strings
In Perl, with interpolation "First: ${first} Last: ${last}\nAge: ${age}"
More template-like
Constructing Strings
In Perl, with interpolation "First: ${first} Last: ${last}\nAge: ${age}"
Don't like the “\n” ?
Constructing Strings
Perl has multiline strings And HERE-DOCs.
my $x = <<“STRING”;First: ${first} Last: ${last}Age: ${age}STRING
Constructing Strings
Embed quotes in other languages “Is this \“readable\”?” “Is this “”better“”?”
Constructing Strings
Embed quotes in Perl 'This is “readable”'
Constructing Strings
Embed quotes in Perl 'This is “readable”' “This isn't too bad either”
Constructing Strings
Embed quotes in Perl 'This is “readable”' “This isn't too bad either” q{ And isn't this “cool”? }
Constructing String Lists
my @list = ( “one”, “two”, “three” “, ... d'oh!
Constructing String Lists
my @list = qw( one two three four five six );
qw() separated lists are easier to write at least...
There's more than one way to do it
Conditionals
if ( $age < 18 ) { ...
if ( ! $age < 18 ) { ...
Conditionals
if ( $age < 18 ) { ...
unless ( $age < 18 ) { ...
Conditionals
if ( $age < 18 ) { ...
unless ( $age < 18 ) { ...
print “Over 18s only”if $age < 18;
Conditionals
if ( $age < 18 ) { ...
unless ( $age < 18 ) { ...
print “Over 18s only”if $age < 18;
print “Over 18s only”unless $age >= 18;
Synonyms
Functionality? Readability
Booleans
or
||
Booleans
or
||
Both mean same thing... But have different precedence 'or' has lowest precedence of any operator
Booleans
<<any expression>> or <<fail>>;
Booleans
<<any expression>> or <<fail>>;
open my $FILEHANDLE, '<', # for reading $filename or die “Couldn't open ${filename}: $!”;
The unspeakable horror... regexes
Regexes
Not just Perl Perl just handles them very well
Regexes
How do you break up a string?
Regexes
How do you break up a string? Hack at it with INSTR()
Regexes
How do you break up a string? Hack at it with INSTR() Regexes
Regexes
How do you break up a string? Hack at it with INSTR() Regexes Parser
Parse::RecDescent, HOP::Parser
Regexes
How do you break up a string? Hack at it with INSTR() Regexes Parser
Parse::RecDescent, HOP::Parser Data structure parser
XML (RSS/XPath etc.), MIME, iCal etc.
Regexes
How do you break up a string? Regexes often hit the sweet spot...
...but they can get ugly when they're not the right tool for the job
Regexes
Perl regexes are builtin No need to
Compile(), .Excecute(), iterate through MatchCollection objects...
Regexes
Perl regexes are builtin my ($first, $last) =
$name =~ /(\w+) (\w+)/;
Regexes
Perl regexes are builtin my ($first, $last) =
$name =~ /(\w+) (\w+)/;
Other languages use strings: “(\\w+) (\\w+)” “\”\\w+\””
Regexes
Perl regexes are builtin my ($first, $last) =
$name =~ /(\w+) (\w+)/;
Other languages use strings “(\\w+) (\\w+)” “\”\\w+\””
All Perl's quoting goodness $url =~ s{^http://} {};
Regexes
Complex regexes are hard to read?
Regexes
Complex regexes are hard to read? Comment!
$_ =~ m/^ # anchor at beginning of line The\ quick\ (\w+)\ fox # fox adjective \ (\w+)\ over # fox action verb \ the\ (\w+) dog # dog adjective (?: # whitespace-trimmed comment: \s* \# \s* # whitespace and comment (.*?) # captured comment text; # (non-greedy!) \s* # any trailing whitespace )? # this is all optional $ # end of line anchor /x; # allow whitespace
Regexes
Named capture in 5.10 /(?<first>\w+) (?<last>\w+)/
Data Structures
Data Structures
Perl is: Dynamic expressionbased
Data Structures
Perl is: Dynamic expressionbased
Can declare most datastructures trivially at runtime.
Data Structures
Declare most datastructures trivially at runtime.
my $person = { name => { first => 'Fred', last => 'Bloggs', }, age => 12, hobbies => [qw/ origami windsurfing /], };
Data Structures http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-linq/#Tip1
C# with Linq int[] a = Enumerable.Repeat (-1, 10).ToArray();
int[] b = Enumerable.Range (0, 10).ToArray()
Data Structures http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-linq/#Tip1
C# with Linq int[] a = Enumerable.Repeat (-1, 10).ToArray();
int[] b = Enumerable.Range (0, 10).ToArray()
“Elegant”
Data Structures http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-linq/#Tip1
C# with Linq int[] a = Enumerable.Repeat (-1, 10).ToArray();
int[] b = Enumerable.Range (0, 10).ToArray()
“Elegant” Perl:
my @a = (-1) x 10; my @b = (0..10);
Data Structures http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-linq/#Tip1
C# with Linq is elegant compared to: int[10] b;for (i=0; i<10; i++) { b[i] = i;}
Data Structures http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-linq/#Tip1
C# with Linq is elegant compared to: int[10] b;for (i=0; i<10; i++) { b[i] = i;}
This is really the functional vs. imperative debate
Functional Programming
Perl is not a functional programming language Borrows some functional features
Functional Programming
Filter @recent = grep {
$_->sent > ($today – ONE_DAY)}@emails;
Functional Programming
Transform @full_names = map {
“$_->{first} $_->{last”}@people;
Functional Programming
A handful of other functions... sort join
Functional Programming
...and modules use List::Util 'sum';print sum(1..10);
Functional Programming
...and first class functions sub double { return 2 * shift } sub triple { return 3 * shift } my %dispatch = (
double => \&double,triple => \&triple,
); my $result = $dispatch{$command}->( $input );
Functional Programming
...including anonymous functions my %dispatch = (
double => sub { 2 * shift },triple => sub { 3 * shift },
)
Functional Programming
...and syntactic sugar my @doubled = map { 2 * $_ } @nums;
First class functions
Enable metaprogramming (OK, there's eval too... if you really need it)
First class functions
Typical cached subroutine
sub my_query { my ($self, %params) = @_; my $cache = $self>get_cache; my $key = $self>get_key( %params ); my $result; return $result if $result = $cache>get($key); $result = $self>expensive_operation(%params); # additional processing $cache>set($key, $result, 20); return $result;}
First class functions
Typical cached subroutine
sub my_query { my ($self, %params) = @_;
my $result = $self>expensive_operation(%params); # additional processing
return $result;}
First class functions
Turn this second into the first my $cached_query =
cache(\&query, %params);
Optionally, install it in the symbol table *query = $cached_query;
Or add syntactic sugar! sub my_query :Cached(time=>20) {
my $result = $self->expensive_operation;# additional processing
return $result;}
Working hard so you don't have to
Caching module
Attribute::Cached Unreleased but see Memoize package table hackery
(manual, but see Class::MOP) Attribute parsing (using Attribute::Handlers)
Surprising fact
Perl programmers are (at best) obsessive about syntax and readable code
Moose
Møøse
Built on scary crack (Class::MOP) http://moose.perl.org/
http://www.iinteractive.com/moose/
Møøse
package Point; use Moose; # automatically turns on strict and warnings
has 'x' => (is => 'rw', isa => 'Int'); has 'y' => (is => 'rw', isa => 'Int');
sub clear { my $self = shift; $self->x(0); $self->y(0); }
Møøse
package Point3D; use Moose;
extends 'Point';
has 'z' => (is => 'rw', isa => 'Int');
after 'clear' => sub { my $self = shift; $self->z(0); };
Møøse
Not just syntactic sugar (Post)modern OO
composition with roles
Møøse - example
HTTP request class package Request; use Moose; use Moose::Util::TypeConstraints; use HTTP::Headers (); use Params::Coerce (); use URI ();
has 'base' => (is => 'rw', isa => 'Uri', coerce => 1); has 'uri' => (is => 'rw', isa => 'Uri', coerce => 1); has 'method' => (is => 'rw', isa => 'Str'); has 'protocol' => (is => 'rw', isa => 'Protocol'); has 'headers' => ( is => 'rw', isa => 'Header', coerce => 1, default => sub { HTTP::Headers->new } );
Møøse - example
Hey! Types!
subtype 'Header' => as 'Object' => where { $_->isa('HTTP::Headers') };
subtype 'Protocol' => as Str => where { /^HTTP\/[0-9]\.[0-9]$/ };
subtype 'Uri' => as 'Object' => where { $_->isa('URI') };
Møøse - example
Coercions working to make using the code easier
coerce 'Uri' => from 'Object' => via { $_->isa('URI') ? $_ : Params::Coerce::coerce( 'URI', $_ ) } => from 'Str' => via { URI->new( $_, 'http' ) };
Thank you
References perl.com/pub/a/1999/03/pm.html
perl.com/pub/a/2004/01/16/regexps.html
igoro.com/archive/7trickstosimplifyyourprogramswithlinq/
moose.perl.org/
blog.timbunce.org/2008/03/08/perlmyths/
Pictures “Larry Wall” by Michael McCracken
flickr.com/photos/michaelmccracken/540924868/
Obfus (BooK, mjd, Les Peters)
“Donald Duck” (Disney)
“Screwdrivers” by ladyheart morguefile.com/archive/?display=134240&
“Horror Masks” by xeniamorguefile.com/archive/?display=93245&
“Swimming Duck" by Yael Lewenstein flickr.com/photos/yaellebel
“Moose” by steve took it flickr.com/photos/stevewall/290510690/