<?xml version="1.0" encoding="windows-1252"?>
<node id="442402" title="Mini HowTo: How to port Perl 5 modules to Perl 6" created="2005-03-25 15:07:01" updated="2005-08-09 03:39:39">
<type id="120">
perlmeditation</type>
<author id="363168">
iblech</author>
<data>
<field name="doctext">
&lt;p&gt;Having ported [http://svn.perl.org/perl6/pugs/trunk/modules/|20 Perl 5 CPAN modules] to [http://dev.perl.org/perl6|Perl 6] in the last few days, these are some things I noticed:&lt;/p&gt;

&lt;readmore&gt;

&lt;ul&gt;

&lt;li&gt;Perl 6 is sexy! :)&lt;/li&gt;

&lt;li&gt;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 :)&lt;/li&gt;

&lt;li&gt;Port a module even if it depends on some other (not yet ported) modules -- the dependencies can be ported later on.&lt;/li&gt;

&lt;li&gt;Often, the translation P5 &amp;rarr; P6 is quite mechanic:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$array[idx]&lt;/code&gt; &amp;rarr;&lt;br /&gt; &lt;code&gt;@array[idx]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;a ? b : c&lt;/code&gt; &amp;rarr;&lt;br /&gt; &lt;code&gt;a ?? b :: c&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$self-&gt;method(...)&lt;/code&gt; &amp;rarr;&lt;br /&gt; &lt;code&gt;.method(...)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sub { my ($self, $a, $b) = @_; ... }&lt;/code&gt; &amp;rarr;&lt;br /&gt; &lt;code&gt;method($a, $b) { ... }&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$x =~ s/.../.../g&lt;/code&gt; &amp;rarr;&lt;br /&gt; &lt;code&gt;$x ~~ s:g/.../.../&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$self-&gt;{foo}&lt;/code&gt; &amp;rarr;&lt;br /&gt; &lt;code&gt;$.foo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$foo = "bar" unless defined $foo&lt;/code&gt; &amp;rarr;&lt;br /&gt; &lt;code&gt;$foo //= "bar" # (//) and (//=) will be in 5.9, too, IIRC&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;if($foo eq "a" or $foo eq "b" or $foo eq "c") {...}&lt;/code&gt; &amp;rarr;&lt;br /&gt; &lt;code&gt;if $foo eq "a"|"b"|"c" {...}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;foreach my $foo (@baz) {...}&lt;/code&gt; &amp;rarr;&lt;br /&gt; &lt;code&gt;for @baz -&gt; $foo {...}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Regular expressions:
&lt;ul&gt;&lt;li&gt;&lt;code&gt;[abc]&lt;/code&gt; &amp;rarr; &lt;code&gt;&lt;[abc]&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[^abc]&lt;/code&gt; &amp;rarr; &lt;code&gt;&lt;-[abc]&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(?:...)&lt;/code&gt; &amp;rarr; &lt;code&gt;[...]&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;

&lt;li&gt;Often, you can remove all that Perl 5 argument parsing and simply substitute it by a nice subroutine|method|whatever signature.&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;
# This Perl 5 exporting code...
require Exporter;
our @ISA    = qw&lt; Exporter &gt;;
our @EXPORT = qw&lt; foo &gt;;
sub foo {...}

# ...becomes this in Perl 6:
sub foo(...) is export {...}
&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;&lt;code&gt;return map {.4.} sort {.3.} grep {.2.} map {.1.}&lt;/code&gt; &amp;rarr;&lt;br /&gt;
&lt;code&gt;map {.1.} ==&gt; grep {.2.} ==&gt; sort {.3.} ==&gt; map {.4.} ==&gt; return&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;Especially Perl 6's translation of Perl 5's getter/setter idiom is cool:&lt;br /&gt;
&lt;code&gt;
# Perl 5
sub get_foo {
  my $self = shift;

  my $ret = $self-&gt;{foo};
  return lc $ret; # always normalize
} 

sub set_foo {
   my ($self, $to) = @_;

   $to =~ s/\s+$//; # strip whitespace at the end
   $self-&gt;{foo} = $to;
}

# Perl 6:
has $:foo;
sub foo() is rw {
  return new Proxy:
    FETCH =&gt; { lc $:foo },
    STORE =&gt; -&gt; $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
&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;If you trust the user to give correct data to accessors, you can also use:&lt;br /&gt;
&lt;code&gt;
has $.foo is rw;
&lt;/code&gt;
Alternatively, if you don't trust The Evil Users:&lt;br /&gt;
&lt;code&gt;
subtype OddInt of Int where { $^n % 2 == 1 }
has OddInt $.foo is rw;
# And then:
$obj.foo = 12; # will die (at compile-time!)
&lt;/code&gt;
&lt;/li&gt;

&lt;/ul&gt;

&lt;/readmore&gt;

&lt;p&gt;You can find a perhaps more recent version of this document in the [http://svn.perl.org/perl6/pugs/trunk/modules/PORTING_HOWTO|Pugs SVN repository].&lt;/p&gt;

&lt;p&gt;--Ingo&lt;/p&gt;</field>
</data>
</node>
