Monday, December 19, 2016

A couple small adventures to mention...

So, I wrote a base class for perl called ABCMeta. It does basically what python's equivalent does, but as a bonus, I do it at compile time. I plan on releasing it as soon as I write more tests to make sure I cover more of the corner cases, but I am super happy with it so far.

Also, I looked into the new signatures stuff in 5.20. I'm not happy. Look at the code below, tell me what I'm doing wrong. Again, compile time safety is where it's at for me at least. Please don't tell me you can see runtime errors coming as you write code.

#!/usr/bin/env perl

package Foo;

use strict;
use fields qw(a b c);

sub new {
    my $self = shift;
    unless ( ref($self) ) {
        $self = fields::new($self);
    }
    return $self;
}

package main;

use strict;
use v5.20;
use feature qw(signatures);
no warnings qw(experimental::signatures);
use Data::Dumper;

#sub mytest( Foo $obj ) : prototype($) { # XXX error types not supported on signatures?!
sub mytest( $obj ) : prototype($) {
    print Dumper($obj);
    eval {
        $obj->{'zz'} = 123; # This error is now a runtime error, not a compile time one, defeating the point of fields :-(
    };
    print "Error trying to set 'zz' on Foo! $@\n" if ( $@ );
}

sub another( $obj ) {
    print Dumper($obj);
}

sub main {
    my Foo $ff = Foo->new();
    # mytest(); # calling this without an argument will throw a compile time error, good!
    # &mytest(); # the sigil doesn't ignore the prototype, huh!? (uncommenting this will throw as well)
    mytest($ff);
    #another(); # more runtime errors, ugh. If I wanted to program in python..
}

&main() if ( ! caller ) ; # if __name__ == 'main'

2 comments:

  1. I am just starting in PERL and do NOT like these errors that are not clear about the real problem, but I am REALLY steamed that when I look them up, I get no real answer in terms of the real problem - just the solution (with no explanation! NANC.NYC@gmail.com Ron Deere

    ReplyDelete
  2. If you are using modern signatures, you do not need the old prototypes.

    sub mytest( $obj )

    states that mytest() takes a single argument, and assigns the argument into $obj. Going on to add

    : prototype($)

    is wasted typing, you're just stating that mytest() takes a single scalar argument.

    I notice the fields.pm documentation has

    my Foo $self = shift;

    referring to the package it is in. Not traditional Perl, but not a traditional package. That missing Foo may be affecting your results.

    ReplyDelete