SlideShare a Scribd company logo
Method::Signatures
Hi.




I'm Michael Schwern.
Some of you may know me as Perl's bitch.
Let's just say CPAN is MY bitch.
I work as an independent consultant (hire me).

I want to talk to you today about a number.
240,000
my $self = shift;




Out of 20 million lines of module code in minicpan

~4000 authors on CPAN
60 per author
Half write more than one module
120 per author
Many don't write OO code, so it gets even higher.

Why do we have to do this?
sub foo {
            my $self = shift;
            my($this, $that) = @_;

                    ...
        }



Traditional thinking has some answers

1) Nothing can handle all the TMTOWDI of Perl.
2) Backwards compat
3) It's not so bad.

I thought this, too. Then I worked at a place with a simple source filter...
sub foo($self, $this, $that) {
             ...
         }




And I coded using that for a year, and it was kinda nice.

Then I left that job.
And I found I missed it.
I wanted that back.
I'd become addicted to its conciseness.
It turns out it is that bad, but you only realize that once you've experienced something better.

But...
Source filters are the root
        of all eval evil.



Because only perl can reliably parse perl.
And a source filter has to run over the whole of your Perl code, not just the one part you care
about.
So source filters are right out.
Which leaves us with...
...nothing.

What was needed was a way to hook into or trick the Perl compiler. To tell us when it saw a
keyword and let us take over. But this is impossible.

When I want something that requires an impossible piece of technology, I talk about it a lot.
And then usually someone makes it possible.
Simon Cozens took a swing at it with a prototype called Method.pm.
use Method;
        sub foo :method {
            $self->bar();
        }




Just after compile time, during the CHECK phase
Method.pm would walk the bytecode of the newly compiled module
Looking for subroutines with the method attribute.
Then it would inject the equivalent of quot;my $self = shiftquot; into the bytecode.
A good idea...
...but it didn't work.

However, it did introduce the technique of injecting code directly into the opcode tree.

It was possible.
Then clkao picked up the torch and ran with it.

He got pretty far, and we got Data::Bind out of it
but still no way to write subroutine prototypes.
Then Matt Trout took a lot of drugs and we got Devel::Declare.

This terrifying hack hooks into Perl's tokenizer and lets you rewrite code just before it's
parsed.
Devel::Declare->setup_for(
             $caller,
             { $keyword =>
                 { const => &parser }
             }
         );




The end result is you can write new block keywords.

It's not trivial by a long shot, but it works and it's reliable.

I put a little sugar on top of that and released...
Method::Signatures
package Foo;

         use Method::Signatures;

         method get($key) {
             $self->{$key};
         }

         method set($key, $val) {
             $self->{$key} = $val;
         }



Isn't that nice?

Method::Signatures rewrites this into normal Perl 5, without a source filter!

So this becomes...
package Foo;

sub get {
    my $self = shift;
    my($key) = @_;

    $self->{$key};
}

sub set {
    my $self = shift;
    my($key, $val) = @_;

    $self->{$key} = $val;
}
use Method::Signatures;

        method get($key) {
            $self->{$key};
        }

        method set($key, $val) {
            $self->{$key} = $val;
        }




There's only one line of scaffolding here to load the module.

Everything else is significant.
sub get {
            my $self = shift;
            my($key) = @_;

                 $self->{$key};
        }

        sub set {
            my $self = shift;
            my($key, $val) = @_;

                 $self->{$key} = $val;
        }

Compare with this.

Less scaffolding means clearer code. The point is made clear.
That's pretty cool.

But if you remember earlier on we said there are 3 excuses why Perl 5 still has no signatures.
1. We don't need em
1. We don't need em




Once you use signatures you'll never go back.
2. Backwards Compatibility
2. Backwards Compatibility




Method::Signatures works back to 5.8.1
3. TMTOWTDI




Well, that's tough.

How do you design a signature system that can do all the things that Perl programmers want
to do?

You get Larry Wall to do it.
Perl 6 might not be ready,

But big chunks of the spec are

So I just lifted the best parts from Synopsis 6.
method new($class: %args) {
             bless {%args}, $class;
         }




Let's say you don't want the invocant to be $self. Ok.

That translates into this...
sub new {
            my $class = shift;
            my %args = @_;
            bless {%args}, $class;
        }




But isn't it wasteful to copy @_? I mean, I could just write this:
sub new {
           my $class = shift;
           bless {@_}, $class;
       }




Ok, fine.
method new($class: @_) {
            bless {@_}, $class;
        }




But what if you want to spell out what all the arguments are?
sub iso_date {
            my $self = shift;
            my %date = @_;

              return quot;$date{year}-$date{month}-$date{day} quot;.
                     quot;$date{hour}:$date{min}:$date{sec}quot;;
        }

        my $date = $obj->iso_date(
            year => 2008, month => 2, day => 23,
            hour => 12,   min   => 23, sec => 0
        );




Well that's just poo.
method iso_date(
            :$year, :$month, :$day,
            :$hour, :$min,   :$sec
        )
        {
            return quot;$year-$month-$day $hour:$min:$secquot;;
        }

        my $date = $obj->iso_date(
            year => 2008, month => 2, day => 23,
            hour => 12,   min   => 23, sec => 0
        );




Ahh.

But what if the user forgets an argument? Defaults would be nice.

(Uhh, this currently doesn't parse)
method iso_date(:$year, :$month, :$day,
                        :$hour, :$min,   :$sec)
        {
            return quot;$year-$month-$day $hour:$min:$secquot;;
        }

        my $date = $obj->iso_date(
            year => 2008, month => 2, day => 23,
            hour => 12,   min   => 23, sec => 0
        );




This will parse.

That'll be fixed.
method iso_date(
    :$year,      :$month = 1, :$day = 1,
    :$hour = 0, :$min    = 0, :$sec = 0
)
{
    return quot;$year-$month-$day $hour:$min:$secquot;;
}


my $date = $obj->iso_date(year => 2008);
method iso_date(
            :$year,      :$month = 1, :$day = 1,
            :$hour = 0, :$min    = 0, :$sec = 0
        )
        {
            return quot;$year-$month-$day $hour:$min:$secquot;;
        }


        my $date = $obj->iso_date();              # ???




But if they forget the year it goes all wrong
So how about required arguments?
method iso_date(
            :$year!,     :$month = 1, :$day = 1,
            :$hour = 0, :$min    = 0, :$sec = 0
        )
        {
            return quot;$year-$month-$day $hour:$min:$secquot;;
        }

        # Class::iso_date missing required argument $year
        my $date = $obj->iso_date();              # error




Now, I want to give you an idea of just how powerful this is.
What if you wanted to do that by hand?
method iso_date(
           :$year!,     :$month = 1, :$day = 1,
           :$hour = 0, :$min    = 0, :$sec = 0
       )
       {
           return quot;$year-$month-$day $hour:$min:$secquot;;
       }




How much code does this represent?
use Carp;

            sub iso_date {
                my $self = shift;
                my(%args) = @_;

                croak(quot;iso_date() missing required argument $yearquot;)
                  unless exists $args{'year'};

                my   $year    =   delete   $args{'year'};
                my   $month   =   exists   $args{'month'}   ?   delete   $args{'month'}   :   1;
                my   $day     =   exists   $args{'day'}     ?   delete   $args{'day'}     :   1;
                my   $hour    =   exists   $args{'hour'}    ?   delete   $args{'hour'}    :   0;
                my   $min     =   exists   $args{'min'}     ?   delete   $args{'min'}     :   0;
                my   $sec     =   exists   $args{'sec'}     ?   delete   $args{'sec'}     :   0;

                croak(quot;iso_date() given extra arguments @{[ keys %args ]}quot;)
                  if keys %args;

                return quot;$year-$month-$day $hour:$min:$secquot;;
            }




All that.

All that scaffolding goes away.

Now you no longer have to choose between being concise and being thorough.

Some more features...
Functions?
func iso_date(
            :$year!,    :$month = 1, :$day = 1,
            :$hour = 0, :$min   = 0, :$sec = 0
        )
        {
            return quot;$year-$month-$day $hour:$min:$secquot;;
        }

        my $date = iso_date( year => 1975, month => 4, day => 20 );




Doesn't do this yet
But it will

Devel::Declare currently can't override sub
Even if it could, I couldn't because...
sub first(&@) {
            my($code, @list) = @_;
            ...
        }




...it already means something.
quot;prototypesquot;
If you don't know what they are, feel lucky.
They don't have much to do with signatures.
People sometimes try to pretend they do.
func first($code, @list) with proto(&@)
        {
            ...
        }




I'd rather keep them separate.
func first($code, @_) with proto(&@)
         {
             ...
         }




A bit more efficient, don't copy the list.
func first($code, @list is alias)
                   with proto(&@)
        {
            ...
        }




Or just alias instead of copying.
method display($text,
                       :$justify = quot;leftquot;, :$enchef = 0)
        {
            ...
        }

        # $text    = quot;Stuffquot;;
        # $justify = quot;rightquot;;
        # $enchef = 0;
        $obj->display(quot;Stuffquot;, justify => quot;rightquot;);




You can mix positional and named arguments.
There are some restrictions to avoid ambiguity.
(Just make sure to put all the positionals first)
They might be relaxed.

We have required arguments, what about optional ones?
method substr(
            $str, $offset, $length?, $replacement?
        ) {
            ...
        }

        $obj->substr(quot;stringquot;, 5);              # good
        $obj->substr(quot;stringquot;);                 # error




Some C programmers might know the quot;constquot;
Says you're not going to change that variable
Both as a promise to the caller
And a check on your code.
method get_page($url is ro) {
           # error
           $url = 'http://instantrimshot.com';
       }




Keeps you honest.
my $method = method ($arg) {
           ...
       };

       $obj->$method($stuff);




Anonymous methods work.
When signatures came up on p5p the biggest argument was over aliasing.

Perl 6 passes by reference. Arguments are aliases, not copies.
Perl 5 passes by copy, but it is possible to alias.
sub strip_ws {
            $_[0] =~ s{^s+}{};
            $_[0] =~ s{s+$}{};
            return;
        }

        my $str = quot; foo                              quot;;
        strip_ws($str);




Some folks thought it would be a good idea to alias by default.
There's some powerful things you can do with it.
It saves memory.
But it's very un-Perl5-ish for a function to change its arguments.
Unless the argument is a reference.
It's possible in Perl 5, but the syntax is yucky so few people do it
(or know about it)
It's like a gun you keep locked up and unloaded.
Making Perl 5 silently pass-by-reference is like walking around with a loaded gun.

So I feel its safer to pass by copy in Perl 5, and leave pass-by-reference to Perl 6 where it's
better built into the language.

BUT!
method strip_ws($str is alias) {
            $str =~ s{^s+}{};
            $str =~ s{s+$}{};
            return;
        }




This is done using the amazing Data::Alias module.

Unfortunately, Data::Alias is busted on Windows < 5.10 or 5.8.9.
Hopefully that will be fixed.
How much performance
   would you pay?
99%?
19.95%?
1%?
1%




In a fair test between Method::Signatures and equivalent hand-written methods.
That means the equivalent is doing all the same parameter validation.
M::S is 1% slower.
This is because M::S is writing out new Perl code at compile time.
So there's no difference.
If you can hand-write it, M::S can do the same.
Turns out that 1% is the difference between a hard coded subroutine and one assigned to an
alias.
This whole adventure started out shortly after 5.10 came out.
Supposing what if we put function signatures into 5.12
Implement the obvious features
Keep it Perl 5 ish
Make sure it can be expanded later
I think we've got it
5.12 or bust!




Half the problem was figuring out what the syntax should be.
Now someone has to implement it inside Perl.
What's missing?




I did a code sprint this week to get all the wow features in before PPW.
But there's still a lot to be done.
sub?




Devel::Declare can't override subs yet, but they're working on it.

Meanwhile, I could write a func() keyword or something.

Once that works, I'll release a unified quot;signaturesquot; pragma.
Debugger is hosed




Devel::Declare causes the debugger to have a fit.
This is the showstopper.
Hopefully there's enough drugs on Earth to help Matt fix it.
Error checking




There's almost none

The guts need work to support more.

Also throw objects.
Types




There's no type or class checks.
It might be added, but I don't want to get into making a Perl 5 type system.
Fortunately, someone else does.
MooseX::Method::Signatures




Does basically the same thing, but with antlers.
Provides a more complete Perl 6 signature implementation.
Florian and I have been swapping features.
Hopefully we'll unify the guts.

Combine Method::Signatures with Moose and Perl 5 is starting to look like a real OO
language!
package Foo;

use Moose;
use MooseX::Method::Signatures;

method hello (Str :$who, Int :$age where { $_ > 0 })
{
    print quot;Hello $who, quot;,
          quot;I am $age years old!quot;;
}

Foo->hello( who => quot;youquot;, age => 42 );
Constraints
method divide(
    $dividend,
    $divisor where { $_ > 0 }
) {
    return $dividend / $divisor;
}
Return signature




There's no way to specify the return signature.
Introspection




Some way to inspect the signature of a method.

The guts need reworking to support that, too.
javaperldoc?




Once you can introspect the signature
You can think about generating documentation
Multi-methods?
method foo($arg?) {
    if( $arg ) {
        ...do this...
    }
    else {
        ...do that...
    }
}
method foo() {
             ...do this...
         }

         method foo($arg) {
             ...do that...
         }




Makes for cleaner code.
This is a distinct possibility.
This is the signature system Perl 5 deserves...
Wish it existed 10 years ago
But we didn't have all this experience and Perl 6 design to draw on.
Thanks...
Simon Cozens
                              clkao
                            Matt Trout



Already mentioned for their foundation work
Larry and the Perl 6
                         Dancers



The Perl 6 Design team for doing all the work on function parameters worthy of Perl
Matthijs van Duin
              (Data::Alias, Sub::Name)



The amazing Data::Alias module which lets quot;is aliasquot; work at full speed
Sub::Name which allows the methods to have the right name in caller()
Florian Ragwitz
         (MooseX::Method::Signatures)




I've been bouncing ideas of Florian.
He fixed attribute handling
And hacked some on Devel::Declare.
Oh wait...
One More Thing




there is one more thing.

And I'm not thrilled about the magic aliasing feature.
# @foo should not change
        $obj->this(@foo);

        # @foo might change
        $obj->that(@foo);




That's really how it should work in Perl 5.

The magic aliases break that.
Now methods can reach out into their caller's data.
Without warning
That's an encapsulation violation.

But I also think Perl 5's referencing syntax can get clunky.
It's annoying to always be working with references inside methods.

Maybe we can have the best of both worlds...
method increment(@args) {
    $_++ for @args;
}

my @nums = (2, 4, 8);

# @nums is now (3, 5, 9)
Foo->increment(@nums);
Method::Signatures




It's on CPAN
http://slideshare.net/schwern




Slides will be on Slideshare.
Thanks!

More Related Content

What's hot

Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order Functions
David Golden
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
Hugo Hamon
 
Coding Horrors
Coding HorrorsCoding Horrors
Coding Horrors
Mark Baker
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
Hugo Hamon
 
Indices APIs - Elasticsearch Reference
Indices APIs - Elasticsearch ReferenceIndices APIs - Elasticsearch Reference
Indices APIs - Elasticsearch Reference
Daniel Ku
 
Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8
XSolve
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
XSolve
 
Adventures in Optimization
Adventures in OptimizationAdventures in Optimization
Adventures in Optimization
David Golden
 
Perl object ?
Perl object ?Perl object ?
Perl object ?
ℕicolas ℝ.
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
Hugo Hamon
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDD
Aleix Vergés
 
20 modules i haven't yet talked about
20 modules i haven't yet talked about20 modules i haven't yet talked about
20 modules i haven't yet talked about
Tatsuhiko Miyagawa
 
Corinna Status 2022.pptx
Corinna Status 2022.pptxCorinna Status 2022.pptx
Corinna Status 2022.pptx
Curtis Poe
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
garux
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
James Titcumb
 
Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)
Michael Schwern
 
Swift internals
Swift internalsSwift internals
Swift internals
Jung Kim
 
Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introduction
Iban Martinez
 
Линзы - комбинаторная манипуляция данными Александр Гранин Dev2Dev v2.0 30.05...
Линзы - комбинаторная манипуляция данными Александр Гранин Dev2Dev v2.0 30.05...Линзы - комбинаторная манипуляция данными Александр Гранин Dev2Dev v2.0 30.05...
Линзы - комбинаторная манипуляция данными Александр Гранин Dev2Dev v2.0 30.05...
Dev2Dev
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
Mark Baker
 

What's hot (20)

Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order Functions
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Coding Horrors
Coding HorrorsCoding Horrors
Coding Horrors
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
Indices APIs - Elasticsearch Reference
Indices APIs - Elasticsearch ReferenceIndices APIs - Elasticsearch Reference
Indices APIs - Elasticsearch Reference
 
Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
 
Adventures in Optimization
Adventures in OptimizationAdventures in Optimization
Adventures in Optimization
 
Perl object ?
Perl object ?Perl object ?
Perl object ?
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDD
 
20 modules i haven't yet talked about
20 modules i haven't yet talked about20 modules i haven't yet talked about
20 modules i haven't yet talked about
 
Corinna Status 2022.pptx
Corinna Status 2022.pptxCorinna Status 2022.pptx
Corinna Status 2022.pptx
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)
 
Swift internals
Swift internalsSwift internals
Swift internals
 
Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introduction
 
Линзы - комбинаторная манипуляция данными Александр Гранин Dev2Dev v2.0 30.05...
Линзы - комбинаторная манипуляция данными Александр Гранин Dev2Dev v2.0 30.05...Линзы - комбинаторная манипуляция данными Александр Гранин Dev2Dev v2.0 30.05...
Линзы - комбинаторная манипуляция данными Александр Гранин Dev2Dev v2.0 30.05...
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
 

Viewers also liked

Víznap Balatonalmádi
Víznap BalatonalmádiVíznap Balatonalmádi
Víznap Balatonalmádi
Softinvent
 
куршская коса в октябре
куршская коса в октябрекуршская коса в октябре
куршская коса в октябре
Polundrala
 
Az Időt A Folyamatosság Jellemzi
Az Időt A Folyamatosság JellemziAz Időt A Folyamatosság Jellemzi
Az Időt A Folyamatosság Jellemzi
Softinvent
 
Who's Afraid Of 2038?
Who's Afraid Of 2038?Who's Afraid Of 2038?
Who's Afraid Of 2038?
Michael Schwern
 
0862758 Vegetarianism
0862758 Vegetarianism0862758 Vegetarianism
0862758 Vegetarianism
Ali G
 
<Free Culture> property
<Free Culture> property<Free Culture> property
<Free Culture> property
Mi Young Yi
 

Viewers also liked (6)

Víznap Balatonalmádi
Víznap BalatonalmádiVíznap Balatonalmádi
Víznap Balatonalmádi
 
куршская коса в октябре
куршская коса в октябрекуршская коса в октябре
куршская коса в октябре
 
Az Időt A Folyamatosság Jellemzi
Az Időt A Folyamatosság JellemziAz Időt A Folyamatosság Jellemzi
Az Időt A Folyamatosság Jellemzi
 
Who's Afraid Of 2038?
Who's Afraid Of 2038?Who's Afraid Of 2038?
Who's Afraid Of 2038?
 
0862758 Vegetarianism
0862758 Vegetarianism0862758 Vegetarianism
0862758 Vegetarianism
 
<Free Culture> property
<Free Culture> property<Free Culture> property
<Free Culture> property
 

Similar to Method::Signatures

Dealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter ScottDealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter Scott
O'Reilly Media
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In Perl
Kang-min Liu
 
Modern Perl
Modern PerlModern Perl
Modern Perl
Marcos Rebelo
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Jesse Vincent
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
Marcello Duarte
 
Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)
Benjamin Bock
 
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxRubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
Dr Nic Williams
 
Perl Teach-In (part 1)
Perl Teach-In (part 1)Perl Teach-In (part 1)
Perl Teach-In (part 1)
Dave Cross
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
Kang-min Liu
 
PHP Unit Testing
PHP Unit TestingPHP Unit Testing
PHP Unit Testing
Tagged Social
 
A limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced RubyA limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced Ruby
Vysakh Sreenivasan
 
Ten modules I haven't yet talked about
Ten modules I haven't yet talked aboutTen modules I haven't yet talked about
Ten modules I haven't yet talked about
acme
 
Esoteric, Obfuscated, Artistic Programming in Ruby
Esoteric, Obfuscated, Artistic Programming in RubyEsoteric, Obfuscated, Artistic Programming in Ruby
Esoteric, Obfuscated, Artistic Programming in Ruby
mametter
 
Modern Perl
Modern PerlModern Perl
Modern Perl
Dave Cross
 
Puppet Camp London 2015 - Helping Data Teams with Puppet
Puppet Camp London 2015 - Helping Data Teams with PuppetPuppet Camp London 2015 - Helping Data Teams with Puppet
Puppet Camp London 2015 - Helping Data Teams with Puppet
Puppet
 
Helping Data Teams with Puppet / Puppet Camp London - Apr 13, 2015
Helping Data Teams with Puppet / Puppet Camp London - Apr 13, 2015Helping Data Teams with Puppet / Puppet Camp London - Apr 13, 2015
Helping Data Teams with Puppet / Puppet Camp London - Apr 13, 2015
Sergii Khomenko
 
SPL, not a bridge too far
SPL, not a bridge too farSPL, not a bridge too far
SPL, not a bridge too far
Michelangelo van Dam
 
Impacta - Show Day de Rails
Impacta - Show Day de RailsImpacta - Show Day de Rails
Impacta - Show Day de Rails
Fabio Akita
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
Dave Cross
 
Writing Modular Command-line Apps with App::Cmd
Writing Modular Command-line Apps with App::CmdWriting Modular Command-line Apps with App::Cmd
Writing Modular Command-line Apps with App::Cmd
Ricardo Signes
 

Similar to Method::Signatures (20)

Dealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter ScottDealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter Scott
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In Perl
 
Modern Perl
Modern PerlModern Perl
Modern Perl
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
 
Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)
 
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxRubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
 
Perl Teach-In (part 1)
Perl Teach-In (part 1)Perl Teach-In (part 1)
Perl Teach-In (part 1)
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
 
PHP Unit Testing
PHP Unit TestingPHP Unit Testing
PHP Unit Testing
 
A limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced RubyA limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced Ruby
 
Ten modules I haven't yet talked about
Ten modules I haven't yet talked aboutTen modules I haven't yet talked about
Ten modules I haven't yet talked about
 
Esoteric, Obfuscated, Artistic Programming in Ruby
Esoteric, Obfuscated, Artistic Programming in RubyEsoteric, Obfuscated, Artistic Programming in Ruby
Esoteric, Obfuscated, Artistic Programming in Ruby
 
Modern Perl
Modern PerlModern Perl
Modern Perl
 
Puppet Camp London 2015 - Helping Data Teams with Puppet
Puppet Camp London 2015 - Helping Data Teams with PuppetPuppet Camp London 2015 - Helping Data Teams with Puppet
Puppet Camp London 2015 - Helping Data Teams with Puppet
 
Helping Data Teams with Puppet / Puppet Camp London - Apr 13, 2015
Helping Data Teams with Puppet / Puppet Camp London - Apr 13, 2015Helping Data Teams with Puppet / Puppet Camp London - Apr 13, 2015
Helping Data Teams with Puppet / Puppet Camp London - Apr 13, 2015
 
SPL, not a bridge too far
SPL, not a bridge too farSPL, not a bridge too far
SPL, not a bridge too far
 
Impacta - Show Day de Rails
Impacta - Show Day de RailsImpacta - Show Day de Rails
Impacta - Show Day de Rails
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
 
Writing Modular Command-line Apps with App::Cmd
Writing Modular Command-line Apps with App::CmdWriting Modular Command-line Apps with App::Cmd
Writing Modular Command-line Apps with App::Cmd
 

Recently uploaded

The importance of Quality Assurance for ICT Standardization
The importance of Quality Assurance for ICT StandardizationThe importance of Quality Assurance for ICT Standardization
The importance of Quality Assurance for ICT Standardization
Axel Rennoch
 
High Profile Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class ...
High Profile Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class ...High Profile Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class ...
High Profile Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class ...
aslasdfmkhan4750
 
The Role of IoT in Australian Mobile App Development - PDF Guide
The Role of IoT in Australian Mobile App Development - PDF GuideThe Role of IoT in Australian Mobile App Development - PDF Guide
The Role of IoT in Australian Mobile App Development - PDF Guide
Shiv Technolabs
 
"Mastering Graphic Design: Essential Tips and Tricks for Beginners and Profes...
"Mastering Graphic Design: Essential Tips and Tricks for Beginners and Profes..."Mastering Graphic Design: Essential Tips and Tricks for Beginners and Profes...
"Mastering Graphic Design: Essential Tips and Tricks for Beginners and Profes...
Anant Gupta
 
Dublin_mulesoft_meetup_Mulesoft_Salesforce_Integration (1).pptx
Dublin_mulesoft_meetup_Mulesoft_Salesforce_Integration (1).pptxDublin_mulesoft_meetup_Mulesoft_Salesforce_Integration (1).pptx
Dublin_mulesoft_meetup_Mulesoft_Salesforce_Integration (1).pptx
Kunal Gupta
 
How to Build a Profitable IoT Product.pptx
How to Build a Profitable IoT Product.pptxHow to Build a Profitable IoT Product.pptx
How to Build a Profitable IoT Product.pptx
Adam Dunkels
 
Data Integration Basics: Merging & Joining Data
Data Integration Basics: Merging & Joining DataData Integration Basics: Merging & Joining Data
Data Integration Basics: Merging & Joining Data
Safe Software
 
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and DisadvantagesBLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
SAI KAILASH R
 
Pigging Unit Lubricant Oil Blending Plant
Pigging Unit Lubricant Oil Blending PlantPigging Unit Lubricant Oil Blending Plant
Pigging Unit Lubricant Oil Blending Plant
LINUS PROJECTS (INDIA)
 
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
Muhammad Ali
 
(CISOPlatform Summit & SACON 2024) Keynote _ Power Digital Identities With AI...
(CISOPlatform Summit & SACON 2024) Keynote _ Power Digital Identities With AI...(CISOPlatform Summit & SACON 2024) Keynote _ Power Digital Identities With AI...
(CISOPlatform Summit & SACON 2024) Keynote _ Power Digital Identities With AI...
Priyanka Aash
 
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdfAcumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
BrainSell Technologies
 
Vertex AI Agent Builder - GDG Alicante - Julio 2024
Vertex AI Agent Builder - GDG Alicante - Julio 2024Vertex AI Agent Builder - GDG Alicante - Julio 2024
Vertex AI Agent Builder - GDG Alicante - Julio 2024
Nicolás Lopéz
 
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptxRPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
SynapseIndia
 
Using LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and MilvusUsing LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and Milvus
Zilliz
 
Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024
aakash malhotra
 
Vulnerability Management: A Comprehensive Overview
Vulnerability Management: A Comprehensive OverviewVulnerability Management: A Comprehensive Overview
Vulnerability Management: A Comprehensive Overview
Steven Carlson
 
Google I/O Extended Harare Merged Slides
Google I/O Extended Harare Merged SlidesGoogle I/O Extended Harare Merged Slides
Google I/O Extended Harare Merged Slides
Google Developer Group - Harare
 
BT & Neo4j: Knowledge Graphs for Critical Enterprise Systems.pptx.pdf
BT & Neo4j: Knowledge Graphs for Critical Enterprise Systems.pptx.pdfBT & Neo4j: Knowledge Graphs for Critical Enterprise Systems.pptx.pdf
BT & Neo4j: Knowledge Graphs for Critical Enterprise Systems.pptx.pdf
Neo4j
 
Active Inference is a veryyyyyyyyyyyyyyyyyyyyyyyy
Active Inference is a veryyyyyyyyyyyyyyyyyyyyyyyyActive Inference is a veryyyyyyyyyyyyyyyyyyyyyyyy
Active Inference is a veryyyyyyyyyyyyyyyyyyyyyyyy
RaminGhanbari2
 

Recently uploaded (20)

The importance of Quality Assurance for ICT Standardization
The importance of Quality Assurance for ICT StandardizationThe importance of Quality Assurance for ICT Standardization
The importance of Quality Assurance for ICT Standardization
 
High Profile Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class ...
High Profile Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class ...High Profile Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class ...
High Profile Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class ...
 
The Role of IoT in Australian Mobile App Development - PDF Guide
The Role of IoT in Australian Mobile App Development - PDF GuideThe Role of IoT in Australian Mobile App Development - PDF Guide
The Role of IoT in Australian Mobile App Development - PDF Guide
 
"Mastering Graphic Design: Essential Tips and Tricks for Beginners and Profes...
"Mastering Graphic Design: Essential Tips and Tricks for Beginners and Profes..."Mastering Graphic Design: Essential Tips and Tricks for Beginners and Profes...
"Mastering Graphic Design: Essential Tips and Tricks for Beginners and Profes...
 
Dublin_mulesoft_meetup_Mulesoft_Salesforce_Integration (1).pptx
Dublin_mulesoft_meetup_Mulesoft_Salesforce_Integration (1).pptxDublin_mulesoft_meetup_Mulesoft_Salesforce_Integration (1).pptx
Dublin_mulesoft_meetup_Mulesoft_Salesforce_Integration (1).pptx
 
How to Build a Profitable IoT Product.pptx
How to Build a Profitable IoT Product.pptxHow to Build a Profitable IoT Product.pptx
How to Build a Profitable IoT Product.pptx
 
Data Integration Basics: Merging & Joining Data
Data Integration Basics: Merging & Joining DataData Integration Basics: Merging & Joining Data
Data Integration Basics: Merging & Joining Data
 
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and DisadvantagesBLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
 
Pigging Unit Lubricant Oil Blending Plant
Pigging Unit Lubricant Oil Blending PlantPigging Unit Lubricant Oil Blending Plant
Pigging Unit Lubricant Oil Blending Plant
 
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
 
(CISOPlatform Summit & SACON 2024) Keynote _ Power Digital Identities With AI...
(CISOPlatform Summit & SACON 2024) Keynote _ Power Digital Identities With AI...(CISOPlatform Summit & SACON 2024) Keynote _ Power Digital Identities With AI...
(CISOPlatform Summit & SACON 2024) Keynote _ Power Digital Identities With AI...
 
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdfAcumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
 
Vertex AI Agent Builder - GDG Alicante - Julio 2024
Vertex AI Agent Builder - GDG Alicante - Julio 2024Vertex AI Agent Builder - GDG Alicante - Julio 2024
Vertex AI Agent Builder - GDG Alicante - Julio 2024
 
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptxRPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
 
Using LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and MilvusUsing LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and Milvus
 
Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024
 
Vulnerability Management: A Comprehensive Overview
Vulnerability Management: A Comprehensive OverviewVulnerability Management: A Comprehensive Overview
Vulnerability Management: A Comprehensive Overview
 
Google I/O Extended Harare Merged Slides
Google I/O Extended Harare Merged SlidesGoogle I/O Extended Harare Merged Slides
Google I/O Extended Harare Merged Slides
 
BT & Neo4j: Knowledge Graphs for Critical Enterprise Systems.pptx.pdf
BT & Neo4j: Knowledge Graphs for Critical Enterprise Systems.pptx.pdfBT & Neo4j: Knowledge Graphs for Critical Enterprise Systems.pptx.pdf
BT & Neo4j: Knowledge Graphs for Critical Enterprise Systems.pptx.pdf
 
Active Inference is a veryyyyyyyyyyyyyyyyyyyyyyyy
Active Inference is a veryyyyyyyyyyyyyyyyyyyyyyyyActive Inference is a veryyyyyyyyyyyyyyyyyyyyyyyy
Active Inference is a veryyyyyyyyyyyyyyyyyyyyyyyy
 

Method::Signatures

  • 3. Some of you may know me as Perl's bitch. Let's just say CPAN is MY bitch. I work as an independent consultant (hire me). I want to talk to you today about a number.
  • 5. my $self = shift; Out of 20 million lines of module code in minicpan ~4000 authors on CPAN 60 per author Half write more than one module 120 per author Many don't write OO code, so it gets even higher. Why do we have to do this?
  • 6. sub foo { my $self = shift; my($this, $that) = @_; ... } Traditional thinking has some answers 1) Nothing can handle all the TMTOWDI of Perl. 2) Backwards compat 3) It's not so bad. I thought this, too. Then I worked at a place with a simple source filter...
  • 7. sub foo($self, $this, $that) { ... } And I coded using that for a year, and it was kinda nice. Then I left that job.
  • 8. And I found I missed it. I wanted that back. I'd become addicted to its conciseness. It turns out it is that bad, but you only realize that once you've experienced something better. But...
  • 9. Source filters are the root of all eval evil. Because only perl can reliably parse perl. And a source filter has to run over the whole of your Perl code, not just the one part you care about. So source filters are right out. Which leaves us with...
  • 10. ...nothing. What was needed was a way to hook into or trick the Perl compiler. To tell us when it saw a keyword and let us take over. But this is impossible. When I want something that requires an impossible piece of technology, I talk about it a lot. And then usually someone makes it possible.
  • 11. Simon Cozens took a swing at it with a prototype called Method.pm.
  • 12. use Method; sub foo :method { $self->bar(); } Just after compile time, during the CHECK phase Method.pm would walk the bytecode of the newly compiled module Looking for subroutines with the method attribute. Then it would inject the equivalent of quot;my $self = shiftquot; into the bytecode. A good idea...
  • 13. ...but it didn't work. However, it did introduce the technique of injecting code directly into the opcode tree. It was possible.
  • 14. Then clkao picked up the torch and ran with it. He got pretty far, and we got Data::Bind out of it
  • 15. but still no way to write subroutine prototypes.
  • 16. Then Matt Trout took a lot of drugs and we got Devel::Declare. This terrifying hack hooks into Perl's tokenizer and lets you rewrite code just before it's parsed.
  • 17. Devel::Declare->setup_for( $caller, { $keyword => { const => &parser } } ); The end result is you can write new block keywords. It's not trivial by a long shot, but it works and it's reliable. I put a little sugar on top of that and released...
  • 19. package Foo; use Method::Signatures; method get($key) { $self->{$key}; } method set($key, $val) { $self->{$key} = $val; } Isn't that nice? Method::Signatures rewrites this into normal Perl 5, without a source filter! So this becomes...
  • 20. package Foo; sub get { my $self = shift; my($key) = @_; $self->{$key}; } sub set { my $self = shift; my($key, $val) = @_; $self->{$key} = $val; }
  • 21. use Method::Signatures; method get($key) { $self->{$key}; } method set($key, $val) { $self->{$key} = $val; } There's only one line of scaffolding here to load the module. Everything else is significant.
  • 22. sub get { my $self = shift; my($key) = @_; $self->{$key}; } sub set { my $self = shift; my($key, $val) = @_; $self->{$key} = $val; } Compare with this. Less scaffolding means clearer code. The point is made clear.
  • 23. That's pretty cool. But if you remember earlier on we said there are 3 excuses why Perl 5 still has no signatures.
  • 24. 1. We don't need em
  • 25. 1. We don't need em Once you use signatures you'll never go back.
  • 28. 3. TMTOWTDI Well, that's tough. How do you design a signature system that can do all the things that Perl programmers want to do? You get Larry Wall to do it.
  • 29. Perl 6 might not be ready, But big chunks of the spec are So I just lifted the best parts from Synopsis 6.
  • 30. method new($class: %args) { bless {%args}, $class; } Let's say you don't want the invocant to be $self. Ok. That translates into this...
  • 31. sub new { my $class = shift; my %args = @_; bless {%args}, $class; } But isn't it wasteful to copy @_? I mean, I could just write this:
  • 32. sub new { my $class = shift; bless {@_}, $class; } Ok, fine.
  • 33. method new($class: @_) { bless {@_}, $class; } But what if you want to spell out what all the arguments are?
  • 34. sub iso_date { my $self = shift; my %date = @_; return quot;$date{year}-$date{month}-$date{day} quot;. quot;$date{hour}:$date{min}:$date{sec}quot;; } my $date = $obj->iso_date( year => 2008, month => 2, day => 23, hour => 12, min => 23, sec => 0 ); Well that's just poo.
  • 35. method iso_date( :$year, :$month, :$day, :$hour, :$min, :$sec ) { return quot;$year-$month-$day $hour:$min:$secquot;; } my $date = $obj->iso_date( year => 2008, month => 2, day => 23, hour => 12, min => 23, sec => 0 ); Ahh. But what if the user forgets an argument? Defaults would be nice. (Uhh, this currently doesn't parse)
  • 36. method iso_date(:$year, :$month, :$day, :$hour, :$min, :$sec) { return quot;$year-$month-$day $hour:$min:$secquot;; } my $date = $obj->iso_date( year => 2008, month => 2, day => 23, hour => 12, min => 23, sec => 0 ); This will parse. That'll be fixed.
  • 37. method iso_date( :$year, :$month = 1, :$day = 1, :$hour = 0, :$min = 0, :$sec = 0 ) { return quot;$year-$month-$day $hour:$min:$secquot;; } my $date = $obj->iso_date(year => 2008);
  • 38. method iso_date( :$year, :$month = 1, :$day = 1, :$hour = 0, :$min = 0, :$sec = 0 ) { return quot;$year-$month-$day $hour:$min:$secquot;; } my $date = $obj->iso_date(); # ??? But if they forget the year it goes all wrong So how about required arguments?
  • 39. method iso_date( :$year!, :$month = 1, :$day = 1, :$hour = 0, :$min = 0, :$sec = 0 ) { return quot;$year-$month-$day $hour:$min:$secquot;; } # Class::iso_date missing required argument $year my $date = $obj->iso_date(); # error Now, I want to give you an idea of just how powerful this is. What if you wanted to do that by hand?
  • 40. method iso_date( :$year!, :$month = 1, :$day = 1, :$hour = 0, :$min = 0, :$sec = 0 ) { return quot;$year-$month-$day $hour:$min:$secquot;; } How much code does this represent?
  • 41. use Carp; sub iso_date { my $self = shift; my(%args) = @_; croak(quot;iso_date() missing required argument $yearquot;) unless exists $args{'year'}; my $year = delete $args{'year'}; my $month = exists $args{'month'} ? delete $args{'month'} : 1; my $day = exists $args{'day'} ? delete $args{'day'} : 1; my $hour = exists $args{'hour'} ? delete $args{'hour'} : 0; my $min = exists $args{'min'} ? delete $args{'min'} : 0; my $sec = exists $args{'sec'} ? delete $args{'sec'} : 0; croak(quot;iso_date() given extra arguments @{[ keys %args ]}quot;) if keys %args; return quot;$year-$month-$day $hour:$min:$secquot;; } All that. All that scaffolding goes away. Now you no longer have to choose between being concise and being thorough. Some more features...
  • 43. func iso_date( :$year!, :$month = 1, :$day = 1, :$hour = 0, :$min = 0, :$sec = 0 ) { return quot;$year-$month-$day $hour:$min:$secquot;; } my $date = iso_date( year => 1975, month => 4, day => 20 ); Doesn't do this yet But it will Devel::Declare currently can't override sub Even if it could, I couldn't because...
  • 44. sub first(&@) { my($code, @list) = @_; ... } ...it already means something. quot;prototypesquot; If you don't know what they are, feel lucky. They don't have much to do with signatures. People sometimes try to pretend they do.
  • 45. func first($code, @list) with proto(&@) { ... } I'd rather keep them separate.
  • 46. func first($code, @_) with proto(&@) { ... } A bit more efficient, don't copy the list.
  • 47. func first($code, @list is alias) with proto(&@) { ... } Or just alias instead of copying.
  • 48. method display($text, :$justify = quot;leftquot;, :$enchef = 0) { ... } # $text = quot;Stuffquot;; # $justify = quot;rightquot;; # $enchef = 0; $obj->display(quot;Stuffquot;, justify => quot;rightquot;); You can mix positional and named arguments. There are some restrictions to avoid ambiguity. (Just make sure to put all the positionals first) They might be relaxed. We have required arguments, what about optional ones?
  • 49. method substr( $str, $offset, $length?, $replacement? ) { ... } $obj->substr(quot;stringquot;, 5); # good $obj->substr(quot;stringquot;); # error Some C programmers might know the quot;constquot; Says you're not going to change that variable Both as a promise to the caller And a check on your code.
  • 50. method get_page($url is ro) { # error $url = 'http://instantrimshot.com'; } Keeps you honest.
  • 51. my $method = method ($arg) { ... }; $obj->$method($stuff); Anonymous methods work.
  • 52. When signatures came up on p5p the biggest argument was over aliasing. Perl 6 passes by reference. Arguments are aliases, not copies. Perl 5 passes by copy, but it is possible to alias.
  • 53. sub strip_ws { $_[0] =~ s{^s+}{}; $_[0] =~ s{s+$}{}; return; } my $str = quot; foo quot;; strip_ws($str); Some folks thought it would be a good idea to alias by default. There's some powerful things you can do with it. It saves memory. But it's very un-Perl5-ish for a function to change its arguments. Unless the argument is a reference. It's possible in Perl 5, but the syntax is yucky so few people do it (or know about it) It's like a gun you keep locked up and unloaded. Making Perl 5 silently pass-by-reference is like walking around with a loaded gun. So I feel its safer to pass by copy in Perl 5, and leave pass-by-reference to Perl 6 where it's better built into the language. BUT!
  • 54. method strip_ws($str is alias) { $str =~ s{^s+}{}; $str =~ s{s+$}{}; return; } This is done using the amazing Data::Alias module. Unfortunately, Data::Alias is busted on Windows < 5.10 or 5.8.9. Hopefully that will be fixed.
  • 55. How much performance would you pay?
  • 56. 99%?
  • 58. 1%?
  • 59. 1% In a fair test between Method::Signatures and equivalent hand-written methods. That means the equivalent is doing all the same parameter validation. M::S is 1% slower. This is because M::S is writing out new Perl code at compile time. So there's no difference. If you can hand-write it, M::S can do the same. Turns out that 1% is the difference between a hard coded subroutine and one assigned to an alias.
  • 60. This whole adventure started out shortly after 5.10 came out. Supposing what if we put function signatures into 5.12 Implement the obvious features Keep it Perl 5 ish Make sure it can be expanded later I think we've got it
  • 61. 5.12 or bust! Half the problem was figuring out what the syntax should be. Now someone has to implement it inside Perl.
  • 62. What's missing? I did a code sprint this week to get all the wow features in before PPW. But there's still a lot to be done.
  • 63. sub? Devel::Declare can't override subs yet, but they're working on it. Meanwhile, I could write a func() keyword or something. Once that works, I'll release a unified quot;signaturesquot; pragma.
  • 64. Debugger is hosed Devel::Declare causes the debugger to have a fit. This is the showstopper. Hopefully there's enough drugs on Earth to help Matt fix it.
  • 65. Error checking There's almost none The guts need work to support more. Also throw objects.
  • 66. Types There's no type or class checks. It might be added, but I don't want to get into making a Perl 5 type system. Fortunately, someone else does.
  • 67. MooseX::Method::Signatures Does basically the same thing, but with antlers. Provides a more complete Perl 6 signature implementation. Florian and I have been swapping features. Hopefully we'll unify the guts. Combine Method::Signatures with Moose and Perl 5 is starting to look like a real OO language!
  • 68. package Foo; use Moose; use MooseX::Method::Signatures; method hello (Str :$who, Int :$age where { $_ > 0 }) { print quot;Hello $who, quot;, quot;I am $age years old!quot;; } Foo->hello( who => quot;youquot;, age => 42 );
  • 70. method divide( $dividend, $divisor where { $_ > 0 } ) { return $dividend / $divisor; }
  • 71. Return signature There's no way to specify the return signature.
  • 72. Introspection Some way to inspect the signature of a method. The guts need reworking to support that, too.
  • 73. javaperldoc? Once you can introspect the signature You can think about generating documentation
  • 75. method foo($arg?) { if( $arg ) { ...do this... } else { ...do that... } }
  • 76. method foo() { ...do this... } method foo($arg) { ...do that... } Makes for cleaner code. This is a distinct possibility.
  • 77. This is the signature system Perl 5 deserves... Wish it existed 10 years ago But we didn't have all this experience and Perl 6 design to draw on.
  • 79. Simon Cozens clkao Matt Trout Already mentioned for their foundation work
  • 80. Larry and the Perl 6 Dancers The Perl 6 Design team for doing all the work on function parameters worthy of Perl
  • 81. Matthijs van Duin (Data::Alias, Sub::Name) The amazing Data::Alias module which lets quot;is aliasquot; work at full speed Sub::Name which allows the methods to have the right name in caller()
  • 82. Florian Ragwitz (MooseX::Method::Signatures) I've been bouncing ideas of Florian. He fixed attribute handling And hacked some on Devel::Declare.
  • 84. One More Thing there is one more thing. And I'm not thrilled about the magic aliasing feature.
  • 85. # @foo should not change $obj->this(@foo); # @foo might change $obj->that(@foo); That's really how it should work in Perl 5. The magic aliases break that. Now methods can reach out into their caller's data. Without warning That's an encapsulation violation. But I also think Perl 5's referencing syntax can get clunky. It's annoying to always be working with references inside methods. Maybe we can have the best of both worlds...
  • 86. method increment(@args) { $_++ for @args; } my @nums = (2, 4, 8); # @nums is now (3, 5, 9) Foo->increment(@nums);