prev Translate Page next

Perl as a Second Language

by Dan Kogai (小飼弾)

This document is also available as:

http://www.dan.co.jp/~dankogai/
yapcasia2008/psl.html

Why should you learn a foreign language?

"I already know $mylanguage. And $mylanguage is turing complete. Why bother learn others?"
There's always more than one way to do it.
More than one language to say it.
Perl 6 (is|are) many languages
-- Larry Wall
But this talk is mainly about Perl 5.
Anyway.
Some language pay more attention to particular subjects.
Englishcousin
にほんごいとこ
中国語表姉、表妹、表兄、表弟、堂姉、堂妹、堂兄、堂弟
Some language pay less attention to particular subjects.
EnglishI speak English.
He speaks English.
にほんご私は日本語を話す。
彼は日本語を話す。
中国語我説漢語。
他説漢語。
It's hard to find what you pay attention.
It's easier to find what they pay attention.
To know your language, know their language.

What Perl is like many languages

Perl is like Python and Ruby

print "Hello, world!";

...not like C

#include <stdio.h>
int main(int argc, char **argv){
  print "Hello, world!";
  return 0;
}

You don't have to say what's obvious -- and tedious.

Perl is like Scheme.

(define Z
  (lambda (f)
    ((lambda (x) (f (lambda (y) ((x x) y))))
     (lambda (x) (f (lambda (y) ((x x) y)))))))

Perl is like Scheme (doesn't look like one, though).

our $Z = sub { my $f = shift;
               sub { my $x = shift; 
                     sub { my $y = shift;
                           $f->($x->($x))
                     }
                 }->(sub { my $x = shift; 
                           sub { my $y = shift; 
                                 $f->($x->($x)) 
                           }
                     });

...not like Haskell.

ch_y = \ f -> (\ x -> f (x x)) (\ x -> f (x x))
Occurs check: cannot construct the infinite type:
  t = t -> t1
  Expected type: t
  Inferred type: t -> t1
In the first argument of `x', namely `x'
In the first argument of `f', namely `(x x)'
You can write a Y-Combinator.

What Perl is NOT like many languages

Perl is NOT like ruby or smalltalk.
irb(main):001:0> 1.class
=> Fixnum
Perl is NOT like ruby or smalltalk.
% perl
print 1->isa('SCALAR');
Can't call method "isa" without a package
  or object reference at - line 1.
Not everything is an object.
Perl is NOT like ruby or smalltalk.
use autobox;
print 1->isa('SCALAR');
1
Though you can make it so with autobox.
Perl (5) is not like other Object Oriented Languages.
package Whatever;
sub new {
  my $class = shift;
  bless { @_ }, $class;
};
# ....
package main;
my $obj = Whatever->new(foo => 42);

does NOT have an OO built-in

That's why you should learn perl if you want to learn OO!
You can learn how to make an object system, not just how to use it.
What is an object?
Data (a datum) which happens to know what it can do.
In Perl 5, Object is just a reference
use CGI;
use Data::Dumper;
my $q = CGI->new;
print Dumper $q;
...blessed to a package (namespace).
$VAR1 = bless( {
                 '.parameters' => [],
                 'use_tempfile' => 1,
                 '.charset' => 'ISO-8859-1',
                 '.fieldnames' => {},
                 'escape' => 1
               }, 'CGI' );
Suppose you have a class like this...
    package Mom;
    sub speak{
        my $self = shift;
        print $self->{name}, ": ", @_, "\n";
    }
    package Daughter;
    our @ISA = qw/Mom/;
    sub new{
        my $class = shift;
        bless { @_ }, $class;
    }
What's going to happen when $hazumi->speak("Hello, world!")?
my $hazumi = Daughter->new(name => 'Hazumi');
$hazumi->speak("Hello, world!");
What's going to happen when $hazumi->speak("Hello, world!")?
  1. perl checks ref $hazumiDaughter
  2. perl checks if Daugher::speak exists → No.
  3. perl checks if Daugher has a parent class, using @ISAMom
What's going to happen when $hazumi->speak("Hello, world!")?
  1. perl checks if Mom::speak exists → yes.
  2. perl Does Mom::speak($hazumi, "Hello, world!")Hazumi: Hello, world!
Fundamentally, Perl 5 added Object Orientation with only two features.
  1. reference - so you can store data in it - including other objects
  2. bless - so the object can find what it can do
Isn't that lazy?
So, in order to implement object orientation, you only need to
  1. Deside how to store data.
  2. Teach the data how to find what to do - method.
If so, isn't there other ways to OO in perl?
Of course!
Inside-out object
    package InsideOut;
    use strict;
    use warnings;
    my %objects;
    sub new {
        my $class = shift;
        bless \eval{ my $scalar }, $class;
    }
    sub DESTROY{
        my $self = shift;
        delete $objects{$self+0};
    }
    sub name{
       my $self = shift;
       $objects{$self+0}{name} = shift if @_;
       $objects{$self+0}{name};
    }
    sub uri{
       my $self = shift;
       $objects{$self+0}{uri} = shift if @_;
       $objects{$self+0}{uri};
    }
    1;
Inside-out object
use InsideOut;
use Data::Dumper;

my $o = InsideOut->new();
$o->name("dankogai");
$o->uri("http://blog.livedoor.jp/dankogai/");
print $o->name, ",", $o->uri, "\n";
print Dumper $o;
% perl insideout.pl
dankogai,http://blog.livedoor.jp/dankogai/
$VAR1 = bless( do{\(my $o = undef)}, 'InsideOut' );

Moose

sentokun
Oops.

Moose

sentokun-real
Excuse me.
Moose - Check Yuval's Talk
  package Point;
  use Moose;

  has 'x' => (is => 'rw', isa => 'Int');
  has 'y' => (is => 'rw', isa => 'Int');

  sub clear {
      my $self = shift;
      $self->x(0);
      $self->y(0);
  }

  package Point3D;
  use Moose;

  extends 'Point';

  has 'z' => (is => 'rw', isa => 'Int');

  after 'clear' => sub {
      my $self = shift;
      $self->z(0);
  };
Perl is not like any language I know.
# Ruby
irb(main):001:0> "1"+"1"
=> "11"
# JavaScript
alert("1"+"1");
% perl -le 'print "1" + "1"'
2
Perl is a context-oriented language
say "1" + "1"; # numeric context
say  1  .  1;  # string  context
Perl is a context-oriented language
say "1" + "1"; # numeric context
say  1  .  1;  # string  context
Perl is a context-oriented language
my $date_in_string = localtime(); # scalar
my ($second, $minute, $hour, $date, $month, $year)
  = localtime(); # list
Some languages are sometimes context-oriented
# ruby
s="1"
i=2
puts "#{s},#{i}" # really "#{s.to_s}, #{i.to_s}";
....but mostly not
% perl -le 'print $ARGV[0]*$ARGV[1]' 10 10
100
% ruby -e 'puts ARGV[0]*ARGV[1]' 10 10
-e:1:in `*': can't convert String
   into Integer (TypeError)
        from -e:1:in `
'
DWIM = Do what I mean
Perlは空気を読む!
You occasionally have to really mean it, though.
% perl -le 'print localtime';
4292114410831340
% perl -le 'print scalar localtime';
Wed May 14 21:30:19 2008
% perl -le 'print "".localtime';
Wed May 14 21:30:32 2008
use B::Deparse to find how perl groks it.
%  perl -MO=Deparse -le 'print"".localtime' ;
BEGIN { $/ = "\n"; $\ = "\n"; }
print '' . localtime;
-e syntax OK
% perl -MO=Deparse,-p -le 'print"".localtime' 
BEGIN { $/ = "\n"; $\ = "\n"; }
print(('' . localtime));
-e syntax OK

What Perl is for

Perl is for everyone.
Like any natural language.
I don't really love English but English does not hate me :-)
No matter how much you hate perl, perl will naver hate you.

Conclusion

What to learn your language? Use perl!
Thank you!
while(my $q = Questions->new){
  $q->answer;
}