Hello,
I have been working on an IDL to Moose translator, and would like some advice on the implementation style.
The framework is:
* parse the OMG IDL 3.5 grammar with Marpa
* produce an AST of it
* use Template::Toolkit to generate a Moose version
The project is at
https://github.com/jddurand/MarpaX-Languages-IDL-AST .
The first generation is trying to avoid sugars as much as possible. Nothing prevent to have another "style" using e.g. MooseX::Declare.
The prerequesites are:
* IDL makes a clear definition of scoped names, i.e. everything declared in an outer scope is visible, although not necessarily used.
- That's why current implementation follows the "scoped" style, i.e. perl packages are embedded each other, like in an IDL, and I map an IDL scoped name to a perl scoped variable.
* The goal is NOT to provide a CORBA system. Only to map IDL to Moose style.
* Following Java, constants and IDL's enum are implemented like roles
* All Basic types are mapped to an internal type library MarpaX::Languages::IDL::AST::MooseX::_BaseTypes
The only gotcha is that I use exclusively roles, and this will not permit that roles that are using other roles would not import some methods, unless Moose hacking a-la MooseX::ComposedBehavior (AFAIK).
If some of you experts could have time to tell me what is superfluous, obviously wrong, etc. I would be glad to hear from you, since I claim to be a Moose beginner.
Let's start with a tiny example: Hello World idl
---
module HelloApp
{
interface Hello
{
string sayHello();
oneway void shutdown();
};
};
---
The generated Moose is currently:
---
#!env perl
package HelloApp {
use Moose::Role;
use MRO::Compat;
use namespace::sweep;
use MooseX::Types -declare => [
qw/
Hello
/
];
our $Hello = role_type Hello, { role => 'HelloApp::Hello' };
package HelloApp::Hello {
use Moose::Role;
use MRO::Compat;
use namespace::sweep;
use MooseX::Params::Validate qw/pos_validated_list/;
use MarpaX::Languages::IDL::AST::MooseX::_BaseTypes qw/:all/;
requires 'sayHello';
around 'sayHello' => sub {
my $orig = shift;
my $self = shift;
return pos_validated_list( [ $self->$orig() ],
{ isa => _stringType } );
};
requires 'shutdown';
around 'shutdown' => sub {
my $orig = shift;
my $self = shift;
$self->$orig();
return undef;
};
};
};
1;
---
And an example of its use would be:
---
package HelloApp::HelloImpl {
use Moose::Role;
use MarpaX::Languages::IDL::AST::MooseX::_BaseTypes qw/:all/;
sub sayHello() {
return "\nHello world !!\n";
};
sub shutdown() {
};
with 'HelloApp::Hello';
};
package HelloAppImpl {
use Moose;
with 'HelloApp', 'HelloApp::HelloImpl';
};
package main;
use HelloAppImpl;
my $HelloAppImpl = HelloAppImpl->new();
$HelloAppImpl->sayHello;
---
As you can see I make explicit use of things like:
- MRO::Compat
- namespace::sweep
- MooseX::Params::Validate
to perform mro resolution, namespace cleaning and non-MooseX-Declare validation of return type (and of parameters when needed).
A more concrete example is the DOM Level 3 Core Specification, available at
http://www.w3.org/TR/DOM-Level-3-Core/idl/dom.idl.
Its Moose generated equivalent is not pasted here, but at this location:
https://gist.github.com/jddurand/1a1dc1f148fe6f77dd5c .
Thanks, Jean-Damien.
ps: sorry I first tried to google interface instead of the mail