Friday, December 4, 2015

Perl6 and subroutines

The old way almost works.  You can't use shift, but if you mind the Perl6 sigil you're good:

   sub hello 
   {
      my $who = @_[0];
      print "hello, $who\n";
   }

> hello('Dave')
hello, Dave


But the new way is  S O   M U C H   B E T T E R:

   sub hello($who)
   {
      say "hello, $who";
   }

> hello('Dave')
hello, Dave


Oh it's about time!  And if you're working with lots of programmers and are paranoid about type checking:

   sub hello(Str $who)
   {
      say "I'm sorry $who, I'm afraid I can't do that";
   }

> hello('Dave')
I'm sorry Dave, I'm afraid I can't do that.


> hello(3)
CHECK FAILED:
Calling 'hello' will never work with argument types (int) (line 1)
    Expected: :(Str $name)





Thursday, December 3, 2015

Perl6: Basic File I/O

NOTE: The I/O Role is explained in detail here: http://doc.perl6.org/type/IO

   my $content = slurp 'text.txt';
   say $content.chars, " chars";

35 chars

   my $output = "And now for some multiline data:
   The first line.
   The second line.
   Anudda line.
   Okay I'm done.";

   spurt "output.txt", $output; 



OK, it wrapped the file handle for me.  That's cool.

File test flags are attached to an IO Role:

   say "text.txt".IO.d;  # am I a dir?
   say "text.txt".IO.e;  # do I exist?
   say "text.txt".IO.f;  # am I a file?

False
True
True

...and if you try it the old way, you'll get the amusing:

   say -e "text.txt";

Confused






Perl6 and Hashes

Mostly like Perl 5 hashes, but there are a couple of new tidbits to amuse.

For example, this 100% traditional Perl line works the same as before:

   my %foo = ( a => 1, b => 2 );
   print keys %foo, "\n";

a b

...but you can also do it in this kinesthetically exotic-looking way:

   my %foo = :a(1), :b(2);
   say %foo.keys

a b

And as before, you can use curly braces to get at values (although don't trip over the sigil):

   say %foo{ 'a' };

1

But the bracket-quote mechanism works too.

   say %foo<a>;

1




Wednesday, December 2, 2015

Perl6: Array Interpolation

   my @foo = 1, 1, 2, 3, 5, 8;
   say "Not interpolated: @foo";
   say "Interpolated: @foo[]";

Not interpolated: @foo
Interpolated: 1 1 2 3 5 8


Tuesday, December 1, 2015

Perl6: comb, map and more arrays


   my @foo = <A B C D>;
   say @foo[2]; # hey, sigils don't "conjugate" anymore.
   say +@foo;      # count items in this array
   say +<A B C D>; # same thing



4

Next, map to apply a transform to each element of an array:

   say @foo.map( { $_ } )
   say <A B C D>.map( { $_ } )  # works with bare arrays too

A B C D
A B C D

   my $foo = 0;
   say <A B C D>.map( { 2 } )   
   say <A B C D>.map( { $foo++ } )

2 2 2 2
0 1 2 3


Now for some fun grep-like stuff: comb.

[http://doc.perl6.org/routine/comb] Searches for a regex in $input and returns a list of all matches (as Str by default, or as Match if $match is True), limited to at most $limit matches.

   my $in = 'ABCDABCDCBAABBDCC';
   say $in.comb( /A/ );      # find all A's
   say $in.comb( /A/, 2 );   # find at most 2 A's

A A A A
A A

   say +$in.comb( /A/ );     # count A's
   say +$in.comb( /B/ );     # count B's
   say +$in.comb( /C/ );     # count C's
   say +$in.comb( /D/ );     # count D's


5
5
3


 It sure would be nice to roll those last four statements together.  Here's one way:
  
   for <A B C D> -> $letter 
   { 
      say +$in.comb( /$letter/ ) 
   }


5
5
3


Slightly terser:

   for <A B C D> { say +$in.comb( /$_/ ) }


5
5
3

Or, using map:

   say <A B C D>.map( { +$in.comb( /$_/ ) } );  

4 5 5 3

Pop Quiz: why did that last statement return its result on one line instead of four lines?

Perl6: run and shell

   run 'echo', "hello Tuesday!"; # external command, no shell
   shell 'ls -ltr';              # runs via system shell.


(When using "shell", metacharacters are interpreted by the shell, including pipes, redirects, environment variable substitutions, etc.)

$ perl6 shell.pl6
hello Tuesday!
total 48
-rw-r--r--  1 rje  501   54 Nov 29 18:10 hello.pl6
-rw-r--r--  1 rje  501  268 Nov 30 07:37 arrays.pl6
-rw-r--r--  1 rje  501  281 Nov 30 07:43 control.pl6
-rw-r--r--  1 rje  501  505 Nov 30 07:49 for.pl6
-rw-r--r--  1 rje  501  264 Nov 30 08:04 input.pl6
-rw-r--r--  1 rje  501   71 Dec  1 08:06 shell.pl6