Monday, January 18, 2010

Sweeter Moose

[Original spanish content]

One comment I received for the previous article was about how would it look using the MooseX::Declare syntax.

This module provides syntax extensions that go far beyond the regular Moose syntactic sugar. Using the deep magic of Devel::Declare, MooseX::Declare creates a whole new syntax very similar to Perl6, for classes and roles in Moose, however, the use of this extension generates mixed feelings for me.

On one side is the look and simplicity of the syntax implemented, but I noticed that changing the syntax in this way will make tools that I take for granted, like perltidy which gives complains about method prototypes, also modules like PPI or vim coloring fail in one way or another.

I am aware that it is all about repairing perltidy, PPI and vim coloring, but the problem is that it is difficult to implement any single sintax that anyone introduces as extensions in CPAN.

I have always argued that one advantage of Devel::Declare is that it allows Perl5 evolve through CPAN modules as TryCatch and MooseX::Declare show syntactic extensions that could eventually be added to Perl5 if widely accepted.

But how will them become widely accepted, if we do not use them because the tools break?

Maybe none of this matters because Rakudo * arrives in march 2010, and everybody will start the great migration to Perl6.

As I do have the same number of arguments for and against, I'll keep pondering which have more weight than others. But in the meantime here are the roles version of the animal's game using MooseX::Declare, for you to get an idea about their own costs and benefits:

 1 #!/usr/bin/env perl
 2 use MooseX::Declare;
 3 
 4 class QuestionNode {
 5     has question => ( is => "ro", isa => "Str", required => 1 );
 6     has [ "yes", "no" ] => ( is => "rw", isa => "Str|QuestionNode", required => 1 );
 7 }
 8 
 9 role AnimalsGame {
10 
11     has tree => (
12         is      => "ro",
13         isa     => "QuestionNode",
14         default => sub {
15             QuestionNode->new(
16                 { question => 'lives in the water', no => 'tiger', yes => 'tiburón' } );
17         }
18     );
19 
20     method play {
21         my $guess = $self->tree;
22         my ( $node, $branch );
23         while ( ref($guess) ) {
24             $node   = $guess;
25             $branch = $self->yes( $node->question ) ? "yes" : "no";
26             $guess  = $node->$branch;
27         }
28         return if $self->yes("Is it a(n) $guess");
29         my $animal = $self->prompt("Animal's name? : ");
30         my $diff   = $self->prompt(
31             "A question true for $animal, but false for $guess: ");
32         $node->$branch( QuestionNode->new( { question => $diff, no => $guess, yes => $animal } ) );
33     }
34 
35 }
36 
37 role ConsoleGame {
38     use Term::ReadLine;
39     use IO::Handle;
40 
41     has title => ( is => "ro", isa => "Str", default => "Animals' game" );
42     has term => (
43         is         => "ro",
44         isa        => "Object",
45         lazy_build => 1,
46         handles    => { prompt => "readline" }
47     );
48 
49     method _build_term {
50         Term::ReadLine->new( $self->title );
51     }
52 
53     method yes(Str $prompt) {
54         while (1) {
55             my $answer = $self->prompt("$prompt? (y/n): ");
56             return ( $2 ? 1 : 0 ) if $answer =~ /^\s*((yes|y)|(no|n))\s*/i;
57             $self->term->OUT->print("Please answer 'y' or 'n'\n");
58         }
59     }
60 
61     method run {
62         $self->play;
63         $self->play while $self->yes("Do you want to play again");
64     }
65 }
66 
67 class Game with AnimalsGame with ConsoleGame {}
68 
69 Game->new->run;

1 comment:

  1. http://www.vim.org/scripts/script.php?script_id=2526

    Perl MooseX::Declare Syntax - perl syntax with Moose ║ and MooseX::Declare keywords : vim online

    ReplyDelete