Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Mini HowTo: How to port Perl 5 modules to Perl 6

by iblech (Friar)
on Mar 25, 2005 at 20:07 UTC ( #442402=perlmeditation: print w/ replies, xml ) Need Help??

Having ported 20 Perl 5 CPAN modules to Perl 6 in the last few days, these are some things I noticed:

  • Perl 6 is sexy! :)
  • Before you start porting a module, make sure you understand the class hierarchy of that module. It helps if you've actually used that module in Perl 5 :)
  • Port a module even if it depends on some other (not yet ported) modules -- the dependencies can be ported later on.
  • Often, the translation P5 → P6 is quite mechanic:
    • $array[idx]
      @array[idx]
    • a ? b : c
      a ?? b :: c
    • $self->method(...)
      .method(...)
    • sub { my ($self, $a, $b) = @_; ... }
      method($a, $b) { ... }
    • $x =~ s/.../.../g
      $x ~~ s:g/.../.../
    • $self->{foo}
      $.foo
    • $foo = "bar" unless defined $foo
      $foo //= "bar" # (//) and (//=) will be in 5.9, too, IIRC
    • if($foo eq "a" or $foo eq "b" or $foo eq "c") {...}
      if $foo eq "a"|"b"|"c" {...}
    • foreach my $foo (@baz) {...}
      for @baz -> $foo {...}
    • Regular expressions:
      • [abc]<[abc]>
      • [^abc]<-[abc]>
      • (?:...)[...]
  • Often, you can remove all that Perl 5 argument parsing and simply substitute it by a nice subroutine|method|whatever signature.
  • # This Perl 5 exporting code... require Exporter; our @ISA = qw< Exporter >; our @EXPORT = qw< foo >; sub foo {...} # ...becomes this in Perl 6: sub foo(...) is export {...}
  • return map {.4.} sort {.3.} grep {.2.} map {.1.}
    map {.1.} ==> grep {.2.} ==> sort {.3.} ==> map {.4.} ==> return
  • Especially Perl 6's translation of Perl 5's getter/setter idiom is cool:
    # Perl 5 sub get_foo { my $self = shift; my $ret = $self->{foo}; return lc $ret; # always normalize } sub set_foo { my ($self, $to) = @_; $to =~ s/\s+$//; # strip whitespace at the end $self->{foo} = $to; } # Perl 6: has $:foo; sub foo() is rw { return new Proxy: FETCH => { lc $:foo }, STORE => -> $to is copy { $to ~~ s/\s+$//; $:foo = $to; }; } # And then: say $obj.foo; $obj.foo = "..."; # Notice: Standard assignment syntax! # Assignments should look line assingments, not like method calls
  • If you trust the user to give correct data to accessors, you can also use:
    has $.foo is rw;
    Alternatively, if you don't trust The Evil Users:
    subtype OddInt of Int where { $^n % 2 == 1 } has OddInt $.foo is rw; # And then: $obj.foo = 12; # will die (at compile-time!)

You can find a perhaps more recent version of this document in the Pugs SVN repository.

--Ingo

Comment on Mini HowTo: How to port Perl 5 modules to Perl 6
Select or Download Code
Re: Mini HowTo: How to port Perl 5 modules to Perl 6
by webfiend (Vicar) on Mar 25, 2005 at 20:55 UTC

    Very nicely put together. I had to read this twice, though. Once for the "Aaagh! So many changes. What are they doing to the grep/map chain? How are those accessors better? Waah!" Then once more, a few minutes later, to recognize how much cleaner this will make a lot of my Perl code. Now I'm all excited again!

      The old grep/map/sort chain works unmodified, too, I just wanted to demonstrate the new pipeline operators. Actually, there are even some other ways too:

      # Perl 5: print join "...", map {...} sort {...} @array; # Perl 6: say (@array.sort:{...} ==> map {...}).join("...");

      TIMTOWTDI :)

      The accessors are especially useful for subclassing:

      class Foo { has $.x; # Explicitly generate an accessor: method x() is rw { return new Proxy: FETCH => {...}, STORE => {...}; } } class Foo::Bar isa Foo { method do_sth { ...; my $var = $.x; # Although used as an variable, the *method* Foo.x is called. # Foo::Bar does *not* directly access the variable. } }

      Now, you may ask, "why is that useful?" -- In Perl 5, when one changed the internal representation of some data in the superclass, but fixed the public accessor methods so they translate between the old representation the user expects and the new one used internally, everything was fine. Except, when there was some subclass: The subclass would still directly access the internal representation, which would, of course, not work.

      Now, with Perl 6, one may subclass freely without having to fear that internal changes of the superclass will affect the subclass. :)

      Generally, the Perl 5 way works in Perl 6, too. But the new ways Perl 6 gives you are often shorter/clearer/more consice/more elegant/more efficient/whatever.

      --Ingo

Re: Mini HowTo: How to port Perl 5 modules to Perl 6
by crenz (Priest) on Mar 30, 2005 at 09:08 UTC

    Thanks for your effort! I have wanted to try out Pugs, but haven't gotten around doing it so far. Can you quickly outline the process to try out a module after porting it -- will Pugs run the module "out of the box", or will I need to install anything else? That information would help me to go and start porting myself.

      you will need to install GHC and the Perl6-Pugs , Pugs as of now does not have support for classes (this is being built and will be available from ver 6.2x) . hope this helps

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://442402]
Approved by dragonchild
Front-paged by dragonchild
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (10)
As of 2014-12-27 04:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (176 votes), past polls