acme's bits: Which logging module?

One of Perl's mottos is "there is more than one way to do it". This is of course a great thing, except when there are two ways to do it and I can't decide which is the better one or the most popular one. Such is it with logging modules - there are two stong candidates: Log::Dispatch and Log::Log4perl. Both do about the same thing, which makes it annoying to decide between the two. Which one do you use? Which one should become the best practice CPAN module for logging?

Read and post comments | Send to a friend

Perl Buzz: Red Hat's patch slows down overloading in Perl

Vipul Ved Prakash, long-time CPAN author and creator of Vipul's Razor, has reported a big slowdown in Red Hat's Perl package.

Some investigation revealed that there’s a long standing bug in Redhat Perl that causes *severe* performance degradation on code that uses the bless/overload combo. The thread on this is here: https://bugzilla.redhat.com/show_bug.cgi?id=379791.

Vipul's analysis is a beautiful rundown of how these kinds of things should be reported, and the techie details should help you decide whether you want to rebuild Perl from source, or wait for updated packages for RHEL and Fedora.

Pete Krawczyk sent me a few comments:

RedHat acknowledges that their patching of Perl caused slowness; if you're doing serious work with default Perl on RedHat, you might want to consider building your own until a proper patch comes along. The problem currently affects Fedora 9, RedHat 5 and spin-offs like CentOS 5. The main symptom is exponential slowdown during operations involving overloaded operators; many common modules (such as JSON and URI) are also affected.

Some other links:

And here's my code to illustrate the slowdown, based on the original code in Vipul's article:

#!/usr/bin/perl

use Time::HiRes;
use overload q(<) => sub {};

my %h;

$|++;

print "Pass#\tPass time\tTotal time\n";
my $bigstart = Time::HiRes::time();
for my $i ( 1..50 ) {
    my $start = Time::HiRes::time();
    for my $j ( 1..1000 ) {
        $h{$i*1000 + $j} = bless [ ] => 'main';
    }
    my $now = Time::HiRes::time();
    printf( "#%2d\t%f\t%f\n", $i, $now-$start, $now-$bigstart );
}

acme's bits: IO


I was microoptimising. I admit it. I was trying to get a little bit of code which read a part of a file going quickly, and I got slightly sidetracked. I noticed that PerlIO had layers, so I played around with the layers and benchmarked things. I noticed that :stdio was quite fast for my one test case, so I compiled a new Perl with ./Configure -des -Uuseperlio -Dprefix=/home/acme/perl-5.10.0-stdio/ to ignore PerlIO and use stdio instead, then benchmarked things (didn't really help). I eventually thought about using unbuffered IO, and noticed that it was much faster than all the others. Aha! I suddenly remember about buffered and unbuffered IO. Buffered IO using seek, read, and write is very handy when reading or writing the whole file. If you are actually doing random access in files then you should use sysseek, sysread and syswrite, doh!


Read and post comments | Send to a friend

Ovid's Journal: GreaseMonkey: Ignoring users on use.perl

Ovid's Journal

Just playing around. It's not overly useful, but it's nice to see it work (and it's fragile). Replace 'some_user_name' below to ignore the user of your choice. No, it doesn't have a lot of features, but it was fun to write :)

// ==UserScript==
// @name           ignore.use.perl
// @namespace      http://publius-ovidius.livejournal.com/
// @description    Hide Annoying Users
// @include        http://use.perl.org/*
// ==/UserScript==

(function() {
    var user = 'some_user_name';
    var href = '//use.perl.org/~'+user+'/';

    // I want zero-width positive look ahead assertions in XPath.  That
    // would eliminate the awful parentNode.parentNode.parentNode;
    // Does this feature exist and I just don't know it?

    var divs = document.evaluate(
        "//div[@class='full']/div/div[@class='details']/a[@href='"+href+"']",
        document,
        null,
        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
        null
    );

    for ( var i=0; i < divs.snapshotLength; i++ ) {
        var node       = divs.snapshotItem(i).parentNode.parentNode.parentNode;
        node.innerHTML = '<p><strong>Ignoring '+user+' via GreaseMonkey</strong></p>';
    }
})();

Ovid's Journal: Why Test::Kit Is Stalled

Ovid's Journal

I want to do more work on Test::Kit, but right now, Schwern's started a very interesting discussion on the Google Test::More project which could eliminate many of the hard parts of this module. I'll keep you posted.

Ovid's Journal: Anyone Using App::Prove::State?

Ovid's Journal

Does anyone use App::Prove::State, module which ships with the new Test::Harness? Outside of the Test::Harness distribution, the only code which I know of which uses it is a quick "which tests are slow?" hack I put together.

I ask this because I'm making some internal changes to this module. I am giving it a proper API to let people extend it in the future. I need to add new features for it, but said features can't live in the core (due to non-core dependencies) and as a result, I need to nail down the interface, but if anyone else is using it, I'd like to not cause them too much pain.

Ovid's Journal: What's That Prototype Again?

Ovid's Journal

Because of some weird mental block, I'm always forgetting the syntax of the prototype command. Thus, I now use this bash alias:

alias prototype="perl -le 'print prototype qq<CORE::@{[+shift]}>'"

And from the command line:

$ prototype bless
$;$

Hmm, bless has a prototype, eh? I should try to override it. I might just be able to create object instantiation graphs with this.

Perl Buzz: How cool Perl 6 really is

Moritz Lenz has started a series of blog posts about moving from Perl 5 to Perl 6, including why some design choices were made, and how you can take advantage of some of the Perl 6 features today in Perl 5. "The target audience are Perl 5 programmers. It is build like a tutorial, but strongly emphasizes the 'why'," he says in his use.perl posting.

Perl Buzz: Big interview with Damian Conway

O'Reilly interviewed Damian Conway at OSCON. There's surprisingly little craziness, but lots of good discussion of programming languages, programming curricula and of course, Perl 6. Oh, and a fair amount of mocking of American accents. Laugh it up, Mr. I-Live-On-A-Giant-Penal-Colony-Island!

The O'Reilly page has a transcription if you don't want to devote 36 minutes of your life to it, but why wouldn't you?

Shlomi Fish's Journal: Recent Hacktivity Summary

Shlomi Fish's Journal

Well, I added more tests to Module-Starter, and while I was writing the tests, I discovered some bugs in it. So now there's a patch with the tests and the bug fixes and another one with only the bug fixes. Both of them are unapplied.

Having been trying to learn Ruby recently, I decided to write a Conway's Game of Life implementation for it. It took me most of one evening to get it working and then part of the other day to make it more idiomatic with the help of the people on Freenode. It felt good in a way.

Then I decided to finally see why my Test-Run failed many tests recently. As it turns out, this was due to broken TAP-Parser compatibility: the skip message in skip_all field now accepts only "SKIP " and not something like "skipping: ". Fixing the Test-Run tests fixed it and I released new versions.

I also noticed that many of the Test-Run-CmdLine plugin had the following pattern:

sub _init
{
    my $self = shift;
    $self->NEXT::_init(@_);
    $self->add_to_backend_plugins("AlternateInterpreters");
}

So I overloaded the construction function, only to add a plugin. I decided to fix this by doing an accumulation of such plugin specifiers in every plugin, and so got only:

sub private_backend_plugins
{
    my $self = shift;

    return [qw(AlternateInterpreters)];
}

Which is much cleaner and less intrusive.

Next on my plate was Freecell Solver. I decided to work on make_pysol_freecell_board.py which is a Python script that generates the initial boards of PySol. The script was crudely written to begin with and it became even cruder as time went by. I decided to give it a serious face-lift. So what I did was:

  • Convert the columns (of the card games) from strings to arrays. Each card was stored there individually.

  • Convert the cards to a class, instead of integers and strings. Create similar classes for managing columsn and boards.

  • Extract many functions and methods.

  • Create a class to manipulate the various game types, and forward the different logic based on it.

  • Pythonised the script by employing some Python paradigms.

You can find what I have so far in the repository. It's much better than what I started with two days ago. Writing such Python code now seems more fun than I recall it, and I actually enjoyed it.

In regards to SMOP, they convinced me to install Ruby-1.9.x under a prefix, which I did, but then it yelled at me for not having a Haskell cabal thingy. Turns out that the Pugs Makefile.PL installs it somewhere under the home-directory, which I didn't want to happen, because I want to keep it tidy. Again, this reminded me of Drivl.com recipe on how to make square corners, and I decided to give up on SMOP again.

And I should note that I was able resolve a long-standing problem I had with XML-LibXML/XML-LibXSLT on my Mandriva system, and now I simplified the XML-Grammar-Fortune build-system.

I also spent some time writing a backup system for some of the Israeli MediaWikis that I manage. This involved a bunch of Perl scripts.

So - Perl, Ruby and Python - all in a few days work. Cheers everybody.

Ovid's Journal: Test::Harness ouput change

Ovid's Journal

It's just a minor change that both Andy and I have wanted for a long time, but I do wonder if it will impact others. Instead of seeing this (use.perl inserts extra spaces, so this might not line up right):

t/proverun......................ok
t/regression....................ok
t/result s.......................ok
t/scheduler.....................ok
t/source........ ................ok
t/spool.........................ok
t/state................. ........ok
t/streams.......................ok

You'll see this:

t/proverun .................... ok
t/regression .................. ok
t/results ..................... ok
t/scheduler ................... ok
t/source ...................... ok
t/spool ....................... ok
t/state ....................... ok
t/streams ..................... ok 

Both of us found this much cleaner. However, this might have unexpected consequences. It also highlights the issue of Test::Harness's long-standing practice of stripping the .t extension from filenames. Why? If we want other extensions, stripping them is probably bad.

Phred's Journal: Where can I find a Ruby hacker? The Beast is winning.

Phred's Journal

Dear LazyPerl,

I had responsibility for a ROR (Ruby on Rails) forum called Beast land squarely in my lap today. Mission critical resource, of course. The box it was being hosted on was upgraded to ruby 1.87, which has some non-backwards compatible upgrades.

Needless to say, the Beast application was not happy, and users cannot post to the forum. Beast 1, Phred 0. The Beast website is also offline. Beast 2, Phred 0.

Do you know a Ruby contractor hacker that can help me even the score? Email fred at redhotpenguin dot com.

Ovid's Journal: iPhone: The Last Straw?

Ovid's Journal

(Note: what follows is why I am tired of Apple. It may not apply to you, so don't grumble at me for it :)

I think for my next laptop, I may just go back to Linux. Apple is really disappointing me.

Before I worked for Kineticode, I had a Sony Vaio running (I think) Debian with the delightfully minimalistic Fluxbox window manager. It wasn't perfect, as I had Linux experts give up trying to get my wireless working and Alsa was just a pain and configuring X was ...

Well, you get the picture. Then David Wheeler, my boss at Kineticode, handed me an iBook. Prior to that my only exposure to Macs had been a girlfriend's Mac which ran System 7. I was dubious about the iBook, but I quickly came to love it. It had the ease of use of Windows but all of the power of Linux (well, all of the power that I needed, that is). It wasn't perfect, but I was pretty happy with it. Sure, lots of things needed X, but hey, I quickly installed that and most of my complaints were gone -- I'm easy to please. Of course, when Fluxbox was segfaulting, I went to the source, fixed the problem and recompiled and I can't do that with Macs, but hey, it's a small price, right?

When I went to buy a new laptop, I upgraded to a MacBook, bought extra RAM and the extended warranty. The first problem I noticed was no WiFi connectivity. This, apparently, was a common problem for MacBooks. It was several months of software updates from Apple before they sorted this mess out and this annoyed the heck out of me because the one thing you don't screw up is people's connectivity.

Of course, this is not the first time Apple's neglected this. Anyone remember the Titanium PowerBook G4 whose metal case looked sexy as hell and killed Wifi connectivity? Don't screw this up, Apple, just don't.

Recently I wanted to install Gimp, which means I need X, which means I need my install disks, which means I need to figure out how to eject the CD currently in my MacBook. Not only is "non-ejecting" CDs a common problem for the new MacBooks, but Apple removed the manual eject hole that older laptops had. This problem would be much less severe if they hadn't done something so stupid. I still need to get to the Apple store and get this fixed, but I'm afraid they'll take my laptop for days on end. I'm an addict, damn it!

So I have iTunes, too. I decided it would be nice to get the album cover art. Turns out I need an Apple Store account. Grumble. OK.

Then it turns out that I need to enter payment information to receive my free cover art!!! What the hell? Apple? Why are you forcing me to fork over financial information if I want this free cover art?

And ignoring the DRM issues (oh, and there are plenty of them), let's talk about connectivity again. You see, I recently went out and bought an "i". You probably know it by another name, but my brother Greg insists upon calling it an "i" because the damned thing has no phone. Well, that's not entirely true. It has great reception, so long as I turn off 3G, but 3G IS THE REASON I BOUGHT THE PHONE!!! I waited months to buy this thing only to find out that I can't use the feature I waited for! Apple, we're talking connectivity here. The one thing you don't screw up is people's connectivity. You can have all sorts of glitches elsewhere, but DO NOT CUT OFF PEOPLE'S FEEDS! I can forgive a hell of a lot, but don't do this to me.

This, and a number of other reasons, is why I think I want to bite the Linux bullet again. Ubuntu is a dream, it's easy to install, its wireless works, and I don't have idiotic DRM issues. Of course, getting Compiz back also makes me drool.

Apple, it was fun while it lasted, but if you can't communicate, this relationship has to end.

(And while we're at it, how many times do I have to try to post this without a "connected failed" error?)

PJF's Journal: Memoirs of an OSCON rockstar, Day 4 (Human Interfaces for Geeks)

Memoirs of an OSCON rockstar, Day 4 (Human Interfaces for Geeks)
My sleeping pattern at OSCON remains sub-optimal. I've crossed timezones, and beause there are so many cool tings to do each evening, and talk practicing and preparation, I find myself going to bed late and sleeping in. I could push myself to wake up early, but being sleepy really wrecks my speaking ability, and after my talk on failure, I've got a reputation to maintain.

I wake up late in the morning, and receive what was the most exicting e-mail I'd received in the entire conference. It's from Allison Randal:

Would you be willing to repeat "An Illustrated History of Failure" [as a plenary]? It'd be 12:45pm Friday.

Woah!

At this point I should mention that presenting a plenary/keynote at OSCON is one of my lifetime goals. I thought that I'd gain a little fame at 2008, a somewhat bigger audience in 2009, and then if I'm very very lucky I could possibly be considered for a plenary/keynote in 2010. I certainly didn't expect it at my first OSCON! The only lifetime goal I thought I would have had a chance of claiming at OSCON was to play Rock Band.

Today I'm presenting "Human Interfaces for Geeks", aka "Hacking Wetware for Fun and Profit", aka "Paul can't make up his mind as to what this talk should be called". My talk is essentially about how people think, how to make them happy, and how making them happy causes them to do your bidding.

When possible, I try to include conference-specific jokes in my talks. In my failure talk I managed to reference Rod::Logic and Dr. Evil Conway. Here, I figured that enough of my audience would have gone to People for Geeks, so last night I had picked Schwern as my victim. Schwern had kindly provided me with some pictures of him as a zombie, and I spent way too long last night creating Schwern in The Sims 2, taking screenshots, turning him into a zombie, and adding general zombie references.

I arrive at OSCON in time for lunch, rather sad that I've missed some of the morning talks I was really looking forward to. I'm also stuck for where I should go after lunch; Anthony Baxter's running the general lightning talks, and I love lightning talks. Anthony runs the lightning talks at OSDC, and Linux.conf.au, and he does a great job of keeping things moving and amusing. I've got stacks of lightning talks up my sleeve, so attending this should have been a no-brainer.

However, Tim Bunce of DBI fame is giving a talk on Ultimate Perl Code Profiling. I'd spoken briefly to Tim earlier in the week, and he told me new the profiler is awesomely cool. I know that I could learn it in my own time, but that will probably take months before I get a round tuit, or I could just attend Tim's talk and download it into my head in one go.

I attend Tim's talk. It is awesome. I know kung-fu.

I sneak out of Tim's talk during question time, because my talk is next. I find coffee and hurry to the room where I'm presenting.

Amazingly, the talk goes down extermely well. I seem to have been gaining popularity over the conference, and now not only is the room stuffed with people, but there's even a handheld video camera in the audience! It seems the audience wasn't disappointed, giving me a 4.9/5.0 across 16 ratings! Wow.

Next up are the Perl Lightning Talks. I wasn't sure what to expect from these, as I've seen lightning talks done really bad, but these are just superb! The Perl community has some great speakers, and the talks are witty, informative, and well presented. Of course, I give one on autodie, in case the conference hasn't heard enough about it already. ;)

The conference ends with Larry's "State of the Onion", and the Perl Foundation Auction. Unfortunately things run a little late, and we lose a few too many audience members before the auction. I pick up a copy of Perl Medic (autographed, yay!), a few assorted other books, and some cool YAPC drinking glasses.

With the main conference over, I head off to a rather exclusive OSCON after-party. Everyone at the party is famous. Everyone. In fact, as r0ml casually comments to me that his son wrote Twisted (python), I realise that everyone and their families are famous.

The party was amazing, although I continue to make the odd faux pas: "Oh, you use identi.ca too?", "No, I'm @evan. I wrote identi.ca." Eventually I get used to the idea that if someone mentions a technology I use, then not only did they write said technology, but they also hold a Nobel Prize, played a role in the original Star Wars, and psychically know what I want to drink next.

Eventually the party gets broken up. It's probably the first time I've ever been to a party so cool that it gets broken up rather than just peters out. I head back to my hotel, discover I'm hungry, and go looking for food at 3am. I find a Mexican place that gives me the most awesome burrito I've ever had in my life, but since I can't for the life of me remember what it was called, when I return there the next day I'm served something which is considerably less than awesome.

Eventually I get back to the hotel, set multiple alarms so I don't miss my talking slot, and sleep.

Posted: 20th August 2008.

Tags:

Bookmark:

Digg this Digg this

Ovid's Journal: How Can I Write This Better?

Ovid's Journal

Using XML::LibXML, I'm trying to determine if two nodes are different. I have the following humiliating code, but it works.

sub _node_differs {
    my ($self,$left,$right) = @_;

    # toStringC14N ensures "canonization" and allows '<title/>' to match
    # '<title></title>'
    my ($left_string, $right_string) = map {
        defined($_) ? ( eval { $_->toStringC14N } || $_->toString ) : ''
    } ( $left, $right );

    if ($left_string ne $right_string) {
        return [ $left, $right ];
    }
    return;
}

What's a "proper" way of doing that? I know I'm missing something obvious.

Perlgeek.de Blog : Changes to Perl 5 Operators

NAME

"Perl 5 to 6" Lesson 11 - Changes to Perl 5 Operators

SYNOPSIS

    # bit wise operators
    5   +| 3;       # 7
    6   +^ 3        # 6
    5   +& 3;       # 1
    "b" ~| "d"      # 'f'
 
    # string concatenation
    'a' ~ 'b'       # 'ab'

    # file tests
    if '/etc/passwd/ ~~ :e { say "exists" }

    # repetition
    'a' x 3         # 'aaa'
    'a' xx 3        # 'a', 'a', 'a'

    # ternary op
    $a == $b ?? 2 * $a !! $b - $a

    # chained comparisons
    if 0 <= $angle < 2 * pi { ... }

DESCRIPTION

All the numeric operators (+, -, /, *, **, %) remain unchanged.

Since |, ^ and & now construct junctions, the bit wise operators have a changed syntax. They now contain a data prefix, so for example +| is bit wise OR with numeric context, and ~^ is one's complement on a string. Bit shift operators changed in the same way.

String concatenation is now ~, the dot . is used for method calls.

File tests are now formulated in Pair notation, Perl 5 -e is now :e. If something other than $_ should be used as the file name, it can be supplied via $filename ~~ :e.

The repetition operator x is now split into two operators: x replicates strings, xx lists.

The ternary operator, formerly $condition ? $true : $false, is now spelled $condition ?? $true !! $false.

Comparison operators can now be changed, so you can write $a < $b < $c and it does what you mean.

MOTIVATION

Many changes to the operators aim at a better Huffman coding, ie give often use things short names (like . for method calls) and seldomly used operators a longer name (like ~& for string bit-wise AND).

The chaining comparison operators are another step towards making the language more natural, and allowing things that are commonly used in mathematical notation.

SEE ALSO

http://perlcabal.org/syn/S03.html#Changes_to_Perl_5_operators

Perlgeek.de Blog : Junctions

NAME

"Perl 5 to 6" Lesson 07 - Junctions

SYNOPSIS

    if $x eq 3|4 {
        say '$x is either 3 or 4'
    }
    say ((2|3|4)+7).perl        # (9|10|11)

DESCRIPTION

Junctions are superpositions of unordered values. Operations on junctions are executed for each item of the junction separately (and maybe even in parallel), and the results are assembled in a junction of the same type.

The junction types only differ when evaluated in boolean context. The types are any, all, one and none.

    Type    Infix operator
    any     |
    one     ^
    all     &

1 | 2 | 3 is the same as any(1..3).

    my Junction $weekday = any <Monday Tuesday Wednesday 
                                Thursday Friday Saturday Sunday>
    if $day eq $weekday {
        say "See you on $day";
    }

In this example the eq operator is called with each pair $day, 'Monday', $day, 'Tuesday' etc. and the result is put in an any-Junction again. As soon as the result is determined (in this case, as soon as one comparison returns True) it can abort the execution of the other comparisons.

This works not only for operators, but also for subs:

    if 2 == sqrt(4 | 9 | 16) {
        say "YaY";
    }

To make this possible, junctions stand outside the normal type hierarchy (a bit):

                    Object
                   /      \
                 Any     Junction
               /  |  \
            All other types

If you want to write a sub that takes a junction and doesn't autothread over it, you have to declare the type of the parameter either as Object or Junction

    sub dump_yaml(Object $stuff) {
        # we hope that YAML can represent junctions ;-)
        ....
    }

A word of warning: Junctions can behave counter-intuitive sometimes. With non-junction types $a != $b and !($a == $b) always mean the same thing. If one of these variables is a junction, that might be different:

    my Junction $b = 3 | 2;
    my $a = 2; 
    say "Yes" if   $a != $b ;       # Yes
    say "Yes" if !($a == $b);       # no output

2 != 3 is true, thus $a != 2|3 is also true. On the other hand the $a == $b comparion returns a single Bool value (True), and the negation of that is False.

MOTIVATION

Perl aims to be ratther close to natural languages, and in natural language you often say things like "if the result is $this or $that" instead of saying "if the result is $this or the result $that". Most programming languages only allow (a translation of) the latter, which feels a bit clumsy. With junctions Perl 6 allows the former as well.

It also allows you to write many comparisons very easily that otherwise require loops.

As an example, imagine an array of numbers, and you want to know if all of them are non-negative. In Perl 5 you'd write something like this:

    # Perl 5 code:
    my @items = get_data();
    my $all_non_neg = 1;
    for (@items){
        if ($_ < 0) {
            $all_non_neg = 0;
            last;
        }
    }
    if ($all_non_neg) { ... }

Or if you happen to know about List::MoreUtils

    use List::MoreUtils qw(all);
    my @items = get_data;
    if (all { $_ >= 0 } @items) { ...  }

In Perl 6 that is short and sweet:

    my @items = get_data();
    if all(@items) >= 0 { ... }

SEE ALSO

http://perlcabal.org/syn/S03.html#Junctive_operators

Perlgeek.de Blog : Building a Huffman Tree With Rakudo

15 months ago I wrote a blog post about Building a Huffman Tree with Perl 6 (German). Back then I used pugs to test it.

Now I tried it with Rakudo Perl revision 29736, and to my delight I discovered that it worked nearly without modification.

(Actually it needed a small modification because I made a mistake in the testing originally, I compared hashes with string semantics. That works in pugs even though it is not specified; in rakudo it doesn't).

I updated my script a bit to do the testing correctly, and used a few more typical Perl 6 idioms:

use Test;
plan 6;

# number of occurences
my @fr = (
    ['a', 45],
    ['b', 13],
    ['c', 12],
    ['d', 16],
    ['e', 9 ],
    ['f', 5 ],
);

# That's what we expect
my %expected = (
    a => '0',
    b => '101',
    c => '100',
    d => '111',
    e => '1101',
    f => '1100'
);

my @c = @fr;

# build the huffman tree
while @c > 1 {
    @c = sort { $^a[1] <=> $^b[1] }, @c;
    my $a = shift @c;
    my $b = shift @c;
    unshift @c, [[$a[0], $b[0]], $a[1] + $b[1]];
}

my %res;

# recursively traverse the tree to build the code
sub traverse ($a, Str $code = ""){
    if $a ~~ Str {
        %res{$a} = $code;
    } else {
        traverse($a[0], $code ~ '0');
        traverse($a[1], $code ~ '1');
    }
}

traverse(@c[0][0]);

# now compare with the expected code:

#say %res;
#say %expected;
for %res.keys -> $k {
    is %res{$k}, %expected{$k}, "Huffman code for letter $k";
}

Perlgeek.de Blog : Magic ARGV (considered harmful)

A bunch of threads on the perl5-porters mailing list made me aware of a rather obscure perl 5 feature.

I was quite familiar with the basic form, which goes like this:

while ( <> ) {
    print;
}

This either reads from all files in turn that were given on the command line, or from STDIN if no file name was provided.

Now <> actually uses open internally, specifically the 2 argument form. Which means that anything that is valid as the second argument to open also works in @ARGV:

local @ARGV = ('fortune |');
priint while <>;

Instead of trying to open a file called fortune |, it actually executes the command fortune and uses it output for the <> "diamond operator".

This feature can be used for quite some tricky and shiny stuff, but it's also dangerous. If your perl program uses <>, it is vulnerable to the command line argument rm -rf * | and similar things, also known as "arbitrary code execution".

Therefore the perl porters are discussing about disabling this feature, and making the old, magic behaviour available with a command line switch or a pragma.

For me the consequence is "don't use <> with possibly untrusted input".

Perlgeek.de Blog : Containers and Values

NAME

"Perl 5 to 6" Lesson 10 - Containers and Values

Synopsis

    my ($x, $y);
    $x := $y;
    $y = 4;
    say $x;             # 4
    if $x =:= $y {
        say '$x and $y are different names for the same thing'
    }

DESCRIPTION

Perl 6 distinguishes between containers, and values that can be stored in containers.

A normal scalar variable is a container, and can have some properties like type constraints, access constraints (for example it can be read only), and finally it can be aliased to other containers.

Putting a value into a container is called assignment, and aliasing two containers is called binding.

    my @a = 1, 2, 3;
    my Int $x = 4;
    @a[0] := $x;     # now @a[0] and $x are the same variable
    @a[0] = 'Foo';   # Error 'Type check failed'

Types like Int and Str are immutable, ie the objects of that type can't be changed; but you can stilll change the variables (the containers, that is) which hold these values:

    my $a = 1;
    $a = 2;     # no surprise here

Binding can also be done at compile time with the ::= operator.

You can check if two things are bound together the the =:= comparison operator.

MOTIVATION

Exporting and importing subs, types and variables is done via aliasing. Instead of some hard-to-grasp typeglob aliasing magic, Perl 6 offers a simple operator.

SEE ALSO

http://perlcabal.org/syn/S03.html#Item_assignment_precedence

Perlgeek.de Blog : Dumping UTF-8 Data

The other day I wrote Perl6::Str, and a small script that I called utf8-dump helped a lot during debugging:

$ echo Überhacker | utf8-dump
\N{LATIN CAPITAL LETTER U WITH DIAERESIS}berhacker

It replaces all non-ASCII-characters with their Unicode name, in a form that can be used in Perl 5 double quoted strings if use charnames qw(:full) is loaded first.

And this is how the script looks:

#!/usr/bin/perl
use strict;
use warnings;
use charnames ();
use Encode qw(decode_utf8);

while (<>){
    $_ = decode_utf8($_);
    s{([^\0-\177])}{N_escape($1)}eg;
    print;
}

sub N_escape {
    return '\N{' . charnames::viacode(ord($_[0])) . '}';
}

Perlgeek.de Blog : Types

NAME

"Perl 5 to 6" Lesson 02 - Types

SYNOPSIS

    my Int $x = 3;
    $x = "foo";         # error
    say $x.WHAT;        # 'Int'
 
    # check for a type:
    if $x ~~ Int {
        say '$x contains an Int'
    }

DESCRIPTION

Perl 6 has types. Everything is an Object in some way, and has a type. Variables can have type constraints, but they don't need to have one.

There are some basic types that you should know about:

    'a string'      # Str
    2               # Int
    3.14            # Num
    (1, 2, 3)       # List

All "normal" builtin types begin with an upper case letter. All "normal" types inherit from Any, and absolutely everything inherits from Object.

You can restrict the type of values that a variable can hold by adding the type name to the declaration.

    my Num $x = 3.4;
    my Int @a = 1, 2, 3;

It is an error to try to put a value into a variable that is of a "wrong" type (ie neither the specified type nor a subtype).

A type declaration on an Arrray is used for its contents, so my Str @s is an array that can only contain strings.

Introspection

You can learn about the direct type of a thing by calling its .WHAT method.

    say "foo".WHAT;     # Str

However if you want to check if something is of a specific type, there is a different way, which also takes inheritance into account and is therefore recommended:

    if $x ~~ Int {
        say 'Variable $x contains an integer';
    }

MOTIVATION

The type system isn't very easy to grok in all its details, but there are good reasons why we need types:

Programming safety

If you declare something to be of a particular type, you can be sure that you can perform certain operations on it. No need to check.

Optimizability

When you have type informations at compile time, you can perform certain optimizations. Perl 6 doesn't have to be slower than C, in principle.

Extensibility

With type informations and multiple dispatch you can easily refine operators for particular types.

SEE ALSO

http://perlcabal.org/syn/S02.html#Built-In_Data_Types,

Perlgeek.de Blog : Contexts

NAME

"Perl 5 to 6" Lesson 06 - Contexts

SYNOPSIS

    my @a = <a b c>
    my $x = @a;
    say $x[2];          # c
    say (~2).WHAT       # Str
    say +@a;            # 3
    if @a < 10 { say "short array"; }

DESCRIPTION

When you write something like this

    $x = @a

in Perl 5, $x contains less information than @a - it contains only the number of items in @a. To preserve all information, you have to explicitly take a reference: $x = \@a.

In Perl 6 it's the other way round: by default you don't lose anything, the scalar just stores the array. This was made possible by introducing a generic item context (called "scalar" in Perl 5) and more specialized numeric, integer and string contexts. Void and List context remain unchanged.

You can force contexts with special syntax.

    syntax      context
    ~stuff      String
    ?stuff      Bool
    +stuff      Numeric
    -stuff      Numeric (also negates)
    $( stuff )  Generic item context
    @( stuff )  List Context

Slice Context

There's also a new context called slice context. It is a list context in which lists don't interpolate.

     @( <a b> Z <c d> )     # <a c b d>
    @@( <a b> Z <c d> )     # (['a', 'c'], ['b', 'd'])

This was introduced after the observation that many built in list functions had two versions - one that returned a flat list, and one that returned a list of lists.

You can force slice context with @@( stuff ).

MOTIVATION

More specific contexts are a way to delay design choices. For example it seems premature to decide what a list should return in scalar context - a reference to the list would preserve all information, but isn't very useful in numeric comparisons. So every possible choice disappoints somebody.

With more specifc context you don't need to make this choice - it returns some sensible default, and all operators that don't like this choice can simply propagate a more specific context.

For some things like the match object the different contexts really enhance their usefulness and beauty.

SEE ALSO

http://perlcabal.org/syn/S02.html#Context

Perlgeek.de Blog : Introduction

NAME

"Perl 5 to 6" - Introduction

SYNOPSIS

    Learn Perl 6 (if you already know Perl 5)
    Learn to love Perl 6
    Understand why

DESCRIPTION

Perl 6 is underdocumented. That's no surprise, because (apart from the specification) writing a compiler for Perl 6 seems to be much more urgent than writing documentation that targets the user.

Unfortunately that means that it's not easy to learn Perl 6, and that you have to have a profound interest in Perl 6 to actually find the motivation to learn it from the specification, IRC channels or from the test suite.

This project, which I'll preliminary call "Perl 5 to 6" (in lack of a better name) attempts to fill that gap with a series of short articles.

Each lesson has a rather limited topic, and tries to explain the two or three most important points with very short examples. It also tries to explain why things changed from Perl 5 to 6, and why this is important. I also hope that the knowledge you gain from reading these lessons is enough to basically understand the Synopsis, which are the canonical source of all Perl 6 wisdom.

To keep the reading easy, each lesson should not exceed 200 lines or 1000 words (but it's a soft limit).

Perhaps the lessons are too short to learn a programming language from them, but I hope that they draw an outline of the language design, which allows you to see its beauty without having to learn the language.

IT'S NOT

This is not a guide for converting Perl 5 to Perl 6 programs. It is also not a comprehensive list of differences. See http://svn.pugscode.org/pugs/docs/Perl6/Perl5/Differences.pod|Perl6::Perl5::Differences instead if you're looking for something like that.

ROADMAP

Already written or in preparation:

    00 Intro
    01 Strings, Arrays, Hashes
    02 Types
    03 Control structures
    04 Subs and Signatures
    05 Objects and Classes
    06 Contexts
    07 Rules
    08 Junctions
    09 Comparisons and Smartmatching
    10 Containers and Binding
    11 Basic Operators
    12 Lazyness
    13 Custom Operators

Planned:

    14 the MAIN sub
    15 Twigils
    16 Enums
    17 Unicode
    18 Scoping

Things that I want to write about, but which I don't know well enough yet:

    Macros
    Meta Object Programming
    Concurrency
    IO

Things that I want to mention somewhere, but don't know where

    .perl method

AUTHOR

Moritz Lenz, http://perlgeek.de/, moritz@faui2k3.org

Perlgeek.de Blog : Parrot and llvm-gcc

Yesterday I built parrot with llvm-gcc 4.2 and llvm 2.2. It was nice to see all tests passing, which IMHO is a good sign for both parrot and llvm.

It gave no speed benefit over the ordinary gcc 4.2, but I'll try again with later versions of llvm and see how it evolves.

I also tried to compile parrot with clang, but couldn't figure out how not to pass linker options to llvm-ld that it doesn't understand, and I gave up rather quickly.

Perlgeek.de Blog : Rules (formerly Regexes)

NAME

"Perl 5 to 6" Lesson 07 - Rules (formerly Regexes)

SYNOPSIS

    grammar URL {
        token TOP {
            <schema> '://' 
            [<hostname> | <ip> ]
            [ ':' <port>]?
            '/' <path>?
        }
        token byte {
            (\d**{1..3}) <?{ $0 < 256 }>

        }
        token ip {
            <byte> [\. <byte> ] ** 3
        }
        token schema {
            \w+
        }
        token host {
            (\w+) ( \. \w+ )*
        }
        token port {
            \d+
        }
        token path {
            <[a..zA..Z0..9-_.!~*'():@&=+$,/]>+

        }
    }

DESCRIPTION

Regexes are one of the areas that has been improved and revamped most in Perl 6. To honour that, an because they aren't "regular expressions" any more, they are now called "rules".

There are three large changes and enhancements to the regexes

Syntax clean up

Many small changes make rules easier to write. For example the dot . matches any character now, the old semantics (anything but newlines) can be achieved with \N.

Modifiers now go at the start of a regex, and non-capturing groups are [..], which are a lot easier to write than the old (?:...).

Nested caputures and match object

In perl 5, a regex like this (a(b))(c) would put ab into $1, b into $2 and c into $3 upon successful match. This has changed. Now $0 (enumeration starts at zero) contains ab, and $0[0] or $/[0][0] contains b. $1 holds c.

Named Rules and Grammars

You can declare regexes with names just like you can with subs and methods. You can refer to these inside other rules with <name>. And you can put multiple rules into grammars, which are just like classes and support inheritance and composition

These changes make rules much easier to write and maintain than Perl 5 regexes.

All of these changes go quite deep, and only the surface can be scratched here.

Syntax clean up

Letter characters (ie underscore, digits and all Unicode letters) match literally, and have a special meaning (they are "metasyntactic") when escaped with a backslash. For all other characters it's the other way round - they are metasyntactic unless escaped.

    literal         metasyntactic
    a  b  1  2      \a \b \1 \2
    \* \: \. \?     *  :  .  ? 

Not all metasyntactic tokens have a meaning (yet). It is illegal to use those without a defined meaning.

There is another way to escape strings in regexes: with quotes.

    m/'a literal text: $#@!!'/

The changed semantics of . has already been mentioned, and that [...] are now non-capturing groups. Char classes are <[...]>, and negated char classes <-[...]>. ^ and $ always match begin and end of the string, to match begin and end of lines use ^^ and $$.

This means that that the /s and /m modifers are gone. Modifiers are now given at the start of a regex, and are spelled as pairs.

    if "abc" ~~ m:i/B/ {
        say "Match";
    }

Modifiers have a short and a long form. The old /x modifier is now the default, i.e. white spaces are ignored.

    short   long            meaning
    -------------------------------
    :i      :ignorecase     ignore case (formerly /i)
    :a      :ignoreaccents  ignore accents
    :g      :global         match as often as possible (/g)
    :s      :sigspace       Every white space in the regex matches
                            (optional) white space
    :P5     :Perl5          Fall back to Perl 5 compatible regex syntax
    :4x     :x(4)           Match four times (works for other numbers as well)
    :3rd    :nth(3)         Third match
    :ov     :overlap        Like :g, but also consider overlapping matches
    :ex     :exhaustive     Match in all possible ways
            :ratchet        Don't backtrack

The :sigspace needs a bit more explanation. It replace all whitespaces in the pattern with <.ws> (that is it calls the rule ws without keeping its result). You can override that rule. By default it matches one or more white spaces if it's enclosed in word characters, and zero or more otherwise.

(There are more new modifiers, but probably not as important as the listed ones).

The Match Object

Every match generates a so-called match object, which is stored in the special variable $/. It is a versatile thing. In boolean context it returns Bool::True if the match succeeded. In string context it returns the matched string, when used as a list it contains the positional captures, and when used as a hash it contains the named captures. The .from and .to methods contains the first and last string positions of the match.

    if 'abcdefg' ~~ m/(.(.)) (e | bla ) $<foo> = (.) / {
        say $/[0][0];           # c
        say $/[0];              # bc
        say $/[1];              # e
        say $/<foo>             # f
    }

$0, $1 etc are just aliases for $/[0], $/[1] etc. Likewise $/<x> and $/{'x'} are aliased to $<x>.

Note that anything that you access via $/[...] and $/{...} is a match object again. This allows you to build real parse trees with rules.

Named Rules and Grammars

Rules can either be used with the old style m/.../, or be declared like subs and methods.

    regex a { ... }
    token b { ... }
    rule  c { ... }

The difference is that token implies the :ratchet modifier (which means no backtracking, like a (?> ... ) group around each part of the regex in perl 5), and rule implies both :ratchet and :sigspace.

To call such a rule (we'll call them all rules, independently with which keyword they were declared) you put the name in angle brackets: <a>. This implicitly anchors the sub rule to its current position in the string, and stores the result in the match object in $/<a>, ie it's a named capture. You can also call a rule without capturing its result by prefixing its name with a dot: <.a>.

A grammar is a group of rules, just like a class (see the SYNOPSIS for an example). Grammars can inherit, override rules and so on.

    grammar URL::HTTP is URL {
        token schema { 'http' }
    }

MOTIVATION

Perl 5 regexes are often rather unreadable, the grammars encourage you to split a large regex into more readable, short fragments. Named captures make the rules more self-documenting, and many things are now much more consistent than they were before.

Finally grammars are so powerful that you can parse about every programming language with them, including Perl 6 itself. That makes the Perl 6 grammar easier to maintain and to change than the perl 5 one, which is written in C and not changable at parse time.

SEE ALSO

http://perlcabal.org/syn/S05.html

Perlgeek.de Blog : Strings, Arrays, Hashes;

NAME

"Perl 5 to 6" Lesson 01 - Strings, Arrays, Hashes;

SYNOPSIS

    my $five = 5;
    print "an interpolating string, just like in perl $five\n";
    say 'say() adds a newline to the output, just like in perl 5.10';

    my @array = 1, 2, 3, 'foo';
    my $sum = @array[0] + @array[1];
    if $sum > @array[2] {
        say "not executed";
    }
    my $number_of_elems = @array.elems;     # or +@array
    my $last_item = @array[*-1];

    my %hash = foo => 1, bar => 2, baz => 3;
    say %hash{'bar'};                       # 2
    say %hash<bar>;                         # same with auto-quoting
    # this is an error: %hash{bar}

DESCRIPTION

Perl 6 is just like perl 5 - only better. Statements are terminated by semicolons. The after the last statement in a block and after a closing curly brace at the end of a line the semicolon is option.

Variables still begin with a sigil (like $, @, %), and many Perl 5 builtins are still mostly unchanged in Perl 6.

Strings

Strings are quoted with double quotes (in which case they are interpolating), or with single quotes. Backslash escapes work just like in Perl 5.

However the interpolation rules have changed a bit. The following things interpolate

    my $scalar = 6;
    my @array = 1, 2, 3;
    say "Perl $scalar";         # 'Perl 6'
    say "An @array[]";          # 'An 1 2 3'
    say "@array[1]";            # '2'
    say "Code: { $scalar * 2 }" # 'Code: 12'

Arrays and hashes only interpolate if followed by an index, empty indexes interpolate the whole data structure.

A block in curly braces is executed as a code block, and the result is interpolated.

Arrays

Arrays variables still begin with the @ sigil. And they always do, even if an index is present.

    my @a = 5, 1, 2;            # no parens needed anymore
    say @a[0];                  # yes, it starts with @
    say @a[0, 2];               # slices also work

Lists are constructed with the Comma operator. 1, is a list, (1) isn't.

Since everything is an object, you can call methods on arrays:

    my @b = @a.sort;
    @b.elems;                   # number of items
    if @b > 2 { say "yes" }     # still works
    @b.end                      # number of last index. Replaces $#array
    my @c = @b.map({$_ * 2 });  # map is also a method, yes

There is a short form for the old qw(..) quoting construct:

    my @methods = <shift unshift push pop end delete sort map>;

Hashes

While Perl 5 hashes are even sized lists, Perl 6 hashes are lists of pairs. Pairs are also used for other things, like named arguments to subs, but more on that later.

Just like with arrays the sigil stays invariant when you index it. And hashes also have methods that you can call on them.

    my %drinks =
        France  => 'Wine',
        Bavaria => 'Beer',
        USA     => 'Coke';

    say "The people in France love ",  %drinks{'France'};
    %drinks.delete('France');

Note that when you access hash elements with %hash{...}, the key is not auto quoted like in Perl 5. So %hash{foo} doesn't access index "foo", but calls the function foo(). The autoquoting isn't gone, it just has a different syntax:

    say %drinks<Bavaria>;

Final Notes

Most builtin methods exists both as a method and as a sub. So you can write both sort @array and @array.sort.

Finally you should know that both [..] and {...} are just method calls with a special syntax, not something tied to arrays and hashes. That means that they are also not tied to a particular sigil.

    my $a = [1, 2, 3];
    say $a[2];          # 3

This means that you don't need special dereferncing syntax, and that you can create objects that can act as arrays, hashes and subs at the same time.

SEE ALSO

http://perlcabal.org/syn/S02.html, http://perlcabal.org/syn/S29.html

Perlgeek.de Blog : Subroutines and Signatures

NAME

"Perl 5 to 6" Lesson 04 - Subroutines and Signatures

SYNOPSIS

    # sub without a signature - perl 5 like
    sub print_arguments {
        say "Arguments:";
        for @_ {
            say "\t$_";
        }
    }

    # Signature with fixed arity and type:
    sub distance(Num $x1, Num $y1, Num $x2, Num $y2) {
        return sqrt ($x2-$x1)**2 + ($y2-$y1)**2;
    }
    say distance(3, 5, 0, 1); 

    # Default arguments
    sub logarithm($num, $base = 2.7183) {
        return log($num) / log($base)
    }
    say logarithm(4);       # uses default second argument
    say logarithm(4, 2);    # explicit second argument

    # named arguments

    sub doit(:$when, :$what) {
        say "doing $what at $when";
    }
    doit(what => 'stuff', when => 'once');  # 'doing stuff at once'
    doit(:when<noon>, :what('more stuff')); # 'doing more stuff at noon'
    # illegal: doit("stuff", "now")

DESCRIPTION

Subroutines are declared with the sub key word, and can have a list of formal parameters, just like in C, Java and most other languages. Optionally these parameters can have type constraints.

Parameters are read-only by default. That can be changed with so-called "traits":

    sub foo($bar) {
        $bar = 2;       # forbidden
    }

    my $x = 2;
    sub baz($bar is rw) {
        $bar = 0;         # allowed
    }
    baz($x); say $x;    # 0

    sub quox($bar is copy){
        $bar = 3;
    }
    quox($x); say $x    # 0

Parameters can be made optional by adding a question mark ? after them, or by supplying a default value.

    sub foo($x, $y?) {
        if $y.defined {
            say "WE CAN HAZ $y"
        }
    }

    sub bar($x, $y = 2 * $x) { 
        ...
    }

Named Parameters

When you invoke a subroutine like this: my_sub($first, $second) the $first argument is bound to the first formal parameter, the $second argument to the second parameter etc., which is why they are called "positional".

Sometimes it's easier to remeber names than numbers, which is why Perl 6 also has named parameters:

    my $r = Rectangle.new( 
            x       => 100, 
            y       => 200, 
            height => 23,
            width  => 42,
            color  => 'black'
    );

When you see something like this, you immediately know what the specific arguments mean.

To define a named parameter, you simply put a colon : before the parameter in the signature list:

    sub area(:$width, :$height) {
        return $width * $height;
    }
    area(width => 2,  height => 3);
    area(height => 3, width => 2 ); # the same
    area(:height<3>, :width<2>);    # the same

In these the variable name is used as the name. You can use a different name, though:

    sub area(:width($w), :height($h)){
        return $w * $h;
    }
    area(width => 2,  height => 3);

Named arguments can only be passed by name, not by position. On the other hand, positional arguments can be passed by name by default.

    sub sqrt($number) { ... };
    sqrt(3);
    sqrt(number => 3); # also works

Slurpy Arguments

Just because you give your sub a signature doesn't mean you have to know the number of arguments in advance. You can define so-called slurpy parameters (after all the regular ones) which use up any remaining arguments:

    sub tail ($first, *@rest){
        say "First: $first";
        say "Rest: @rest[]";
    }
    tail(1, 2, 3, 4);           # "First: 1\nRest: 2 3 4\n"

Interpolation

By default arrays aren't interpolated in argument lists, so unlike in Perl 5 you can write something like this:

    sub a($scalar1, @list, $scalar2){
        say $scalar2;
    }

    my @list = "foo", "bar";
    a(1, @list, 2);                  # 2

That also means that by default you can't use a list as an argument list:

    my @indexes = 1, 4;
    say "abc".substr(@indexes)       # error!

You can achieve the desired behaviour with a prefix |

    say "abcdefgh".substr(|@indexes) # bcde

Multi Subs

You can actually define multiple subs with the same name but with different parameter lists:

    multi sub my_substr($str) { ... }                          # 1
    multi sub my_substr($str, $start) { ... }                  # 2
    multi sub my_substr($str, $start, $end) { ... }            # 3
    multi sub my_substr($str, $start, $end, $subst) { ... }    # 4

Now whenever you call such a sub, the one with the matching parameter list will be chosen.

The multis don't have to differ in the arity (ie number of arguments), they can also differ in the type of the parameters:

    multi sub frob(Str $s) { say "Frobbing String $s"  }
    multi sub frob(Int $i) { say "Frobbing Integer $i" }

    frob("x")       # Frobbing String x
    frob(2)         # Frobbing Inteteger 2

MOTIVATION

Nobody will doubt the usefulness of explicit sub signatures: less typing, less duplicate argument checks, and more self-documenting code. The value of named parameters has also been discussed already.

Multi subs are very useful because they allow builtins to be overridden for new types. Let's assume you want a version of Perl 6 which is localized to handle turkish strings correctly, which have unsual rules for case conversions.

Instead of modifying the language, you can just introduce a new type TurkishStr, and add multi subs for the builtin functions:

    sub uc(TurkishStr $s) { ... }

Now all you have to do is to take care that your strings have the type that corresponds to their language, and then you can use uc just like the normal builtin function.

Since operators are also subs, that refinement works for operators too.

SEE ALSO

http://perlcabal.org/syn/S06.html

Perlgeek.de Blog : Basic Control Structures

NAME

"Perl 5 to 6" Lesson 03 - Basic Control Structures

SYNOPSIS

    if $percent > 100  {
        say "weird mathematics";
    }
    for 1..3 {
        # using $_ as loop variable
        say 2 * $_;
    }
    for 1..3 -> $x {
        # with explicit loop variable
        say 2 * $x;
    }

    while $stuff.is_wrong {
        $stuff.try_to_make_right;
    }

    die "Access denied" unless $password eq "Secret";

DESCRIPTION

Most Perl 5 control structures are quite similar in Perl 6. The biggest visual difference is that you don't need a pair of parenthesis after if, while, for etc.

Branches

if is mostly unchanged, you can still add elsif and else branches. unless is still there, but no else branch is allowed after unless.

    if $sheep == 0 {
        say "How boring";
    } elsif $sheep == 1 {
        say "One lonely sheep";
    } else {
        say "A herd, how lovely!";
    }

You can also use if and unless as a statement modifier, i.e. after a statements:

    say "you won" if $answer == 42;

Loops

You can manipulate loops with next and last just like in Perl 5.

The for-Loop is now only used to iterate over lists. By default the standard variable $_ is used, unless an explicit loop variable is given.

    for 1..10 -> $x {
        say $x;
    }

The -> $x { ... } thing is called a "pointy block" and is something like an anonymous sub, or a lambda in lisp.

You can also use more than one loop variable:

    for 0..5 -> $even, $odd {
        say "Even: $even \t Odd: $odd";
    }

This is also how you iterate over hashes:

    my %h = a => 1, b => 2, c => 3;
    for %h.kv -> $key, $value {
        say "$key: $value";
    }

The C-style for-loop is now called loop:

    loop (my $x = 1; $x < 100; $x = $x**2) {
        say $x;
    }

SEE ALSO

http://perlcabal.org/syn/S04.html#Conditional_statements

Perlgeek.de Blog : Objects and Classes

NAME

"Perl 5 to 6" Lesson 06 - Objects and Classes

SYNOPSIS

    class Shape {
        method area { ... }    # literal '...'
        has $.colour is rw;

    }

    class Rectangle is Shape {
        has Num $.width;
        has Num $.height;

        method area {
            $!width * $!height;
        }
    }

    my $x = Rectangle.new(
            width   => 30,
            height  => 20,
            colour  => 'black',
        );
    say $x.area;                # 600
    say $x.colour;              # black
    $x.colour = 'blue';

DESCRIPTION

Perl 6 has an object model that is much more fleshed out than the Perl 5 one. It has keywords for creating classes, roles, attributes and methods, and has encapsulated private attributes and methods.

There are two ways to declare classes

    class ClassName;
    # class definition goes here

The first one begins with class ClassName; and stretches to the end of the file. In the second one the class name is followed by a block, and all that is inside the blocks is considered to be the class definition.

    class YourClass {
        # class definition goes here
    }
    # more classes or other code here

Methods

Methods are declared with the method key word. Inside the the method you can use the self keyword to refer to the object on which the method is called (the invocant).

You can also give the invocant a different name by adding a first parameter to the signature list and append a colon : to it.

Public methods can be called with the syntax $object.method if it takes no arguments, and $object.method(@args) or $object.method: @args if it takes arguments.

    class SomeClass {
        # these two methods do nothing but return the invocant
        method foo {
            return self;
        }
        method bar($s: ) {
            return $s;
        }
    }
    my SomeClass $x .= new;
    $x.foo.bar                      # same as $x

(The my SomeClass $x .= new is actually a shorthand for my SomeClass $x .= SomeClass.new. It works because the type declaration fills the variable with a "proto object" of SomeClass, which is an object representation of the the type.)

Methods can also take additional arguments just like subs.

Private methods can be declared with my method, and called with self!method_name.

    class Foo {
        my method private($frob) {
            return "Frobbed $frob";
        }

        method public {
            say self!private("foo");
        }
    }

Private methods can't be called from outside the class.

Attributes

Attributes are declared with the has key word, and have a "twigil", that is a special character after the sigil. For private attributes that's a bang !, for public attributes it's the dot .. Public attributes are just private attributes with a public accessor.

    class SomeClass {
        has $!a;
        has $.b;
        has $.c is rw;

        method do_stuff {
            # you can use the private name instead of the public one
            # $!b and $.b are really the same thing
            return $!a + $!b + $!c;
        }
    }
    my $x = SomeClass.new;
    say $x.a;       # ERROR!
    say $x.b;       # ok
    $x.b = 2;       # ERROR!
    $x.c = 3;       # ok

Inheritance

Inheritance is done through an is trait.

    class Foo is Bar { 
        # class Foo inherits from class Bar
        ...
    }

All the usual inheritance rules apply - methods are first looked up on the direct type, and if that fails, on the parent class (recursively). Likewise the type of a child class is conformant to that of a parent class:

        class Bar { }
        class Foo is Bar { }
        my Bar $x = Foo.new();

In this example the type of $x is Bar, and it is allowed to assign an object of type Foo to it, because "every Foo is a Bar".

Classes can inherit from multiple other classes:

    class ArrayHash is Hash is Array { 
        ...
    }

Roles and Composition

In general the world isn't hierarchical, and thus sometimes it's hard to press everything into an inheritance hierarchy. Which is one of the reasons why Perl 6 has Roles. Roles are quite similar to classes, except you can't create objects directly from them. While classes are intended primarily for type conformance, roles are the primary means for code reuse in Perl 6.

    role Paintable {
        has $.colour is rw;
        method paint { ... }
    }
    class Shape {
        method area { ... }
    }

    class Rectangle is Shape does Paintable {
        has $.width;
        has $.height;
        method area {
            $!width * $!height;
        }
    }

SEE ALSO

http://perlcabal.org/syn/S12.html

Perlgeek.de Blog : Comparing and Matching

NAME

"Perl 5 to 6" Lesson 09 - Comparing and Matching

SYNOPSIS

    "ab"    eq      "ab"    True
    "1.0"   eq      "1"     False
    "a"     ==      "b"     True
    "1"     ==      1.0     True
    1       ===     1       True
    [1, 2]  ===     [1, 2]  False
    $x = [1, 2];
    $x      ===     $x      True
    $x      eqv     $x      True
    [1, 2]  eqv     [1, 2]  True
    1.0     eqv     1       False

    'abc'   ~~      m/a/    True
    'abc'   ~~      Str     True
    'abc'   ~~      Int     False
    Str     ~~      Any     True
    Str     ~~      Num     False
    1       ~~      0..4    True
    -3      ~~      0..4    False

DESCRIPTION

Perl 6 still has string comparison operators (eq, lt, gt, le, ge, ne; cmp is now called leg) that evaluate their operands in string context. Similarly all the numeric operators from Perl 5 are still there.

Since objects are more than blessed references, a new way for comparing them is needed. === returns only true for identical values. For immutable types like numbers or Strings that is a normal equality tests, for other objects it only returns True if both variables refer to the same object (like comparing memory addresses in C++).

eqv tests if two things are equivalent, ie if they are of the same type and have the same value. Two identically constructed data structures are equivalent.

Smart matching

Perl 6 has a "compare everything" operator, called "smart match" operator, and spelled ~~.

For immutable types it is a simple equality comparison. A smart match against a type checks for type conformance. A smart match against a regex matches the regex. Matching a scalar against a Range object checks if that scalar is included in the range.

There are other, more advanced forms of matching: for example you can check if an argument list (Capture) fits to the parameter list (Signature) of a subroutine, or apply file test operators (like -e in Perl 5).

What you should remeber is that any "does $x fit to $y?"-Question will be formulated as a smart match in Perl 6.

SEE ALSO

http://perlcabal.org/syn/S03.html#Nonchaining_binary_precedence