Modern Perl Books, a Modern Perl Blog: How About a Shetland Ponie?

Rakudo Star is out, and so begins the next great wave of interest and use of Perl 6. The next several releases will improve performance, fix bugs, add features, port or create more libraries, and—in all likelihood—improve and otherwise clarify the Perl 6 specification.

The Perl ecosystem has room for other projects, however.

For example, one of the clearest benefits Perl 6 has over Perl 5 is its portability to other virtual machines and runtimes. By design Perl 6 encourages multiple implementations. Perl 5 is its own specification; in many places, what Perl 5 is is solely what Perl 5 happens to do. Sometimes that behavior gets enshrined in the specification tests, but other times it's folklore and institutional community knowledge.

Just as Parrot's Lorito project intends to make Parrot at least an order of magnitude faster, so too a reorganization of Perl 5 internals could make amazing things more possible.

What if there were a project to implement a minimal set of Perl 5 on the Parrot virtual machine as a prototype and exploration of how much of Perl 5 you can support, the effort it takes to do so, and what kind of utility you can expect? Parrot's compiler tools let the Rakudo developers write most of Perl 6 in Perl 6; surely it's possible to write Perl 5 in a similar fashion. (Credit to other projects such as Rubinius and PyPy for demonstrating that such things are possible.)

I know other projects have attempted this in the past. Perhaps the best place to steal information is Bradley Kuhn's masters thesis, Considerations on Porting Perl to the Java Virtual Machine.

As Jesse wrote in his comments, bug-for-bug compatibility isn't necessary. Nor is full compliance with the existing Perl 5 test suite. A simple proof of concept to produce the 80% of Perl 5 most people use in most programs should suffice. (Parrot gives you a lot of that anyway.)

As a bonus, you get cheap and easy interoperability with Perl 5, access to Parrot features such as multidispatch, grammars, continuations, and bytecode serialization, and you could even replace some of the uses of Perl 5 within Parrot's and perhaps even Rakudo's configuration and build processes.

It doesn't even have to be a pony of full size.

Perlsphere: Sofia.pm

I have started work on reinvigorating the seemingly dead Sofia.pm, the perl mongers group in Sofia, Bulgaria. Recently I took over the administration of the mailing list, and just now I have launched a fresh new website. There are many perl users here, as became evident from the first and second perl workshops that took place (ash++) in the last two years, so I am confident this will be an active and stable group. So, if you are a perl user from Bulgaria, make sure you get on the mailing list.

use Perl Journal Search: Perl 6 Is The Language Your Language Could Smell Like (2010.07.29 15:24)

Perl 6 Is The Language Your Language Could Smell Like (2010.07.29 15:24)
Hello programmers. Look at your code, now at Perl 6, now back at your code, now back at Perl 6! Sadly, your code is not written in Perl 6. But if you use Rakudo Star then Perl 6 is the language your code could be written in!Now Microsoft scented!

Perlsphere: Rakudo Star - a useful, usable, "early adopter" distribution of Perl 6

On behalf of the Rakudo and Perl 6 development teams, I'm happy to announce the July 2010 release of "Rakudo Star", a useful and usable distribution of Perl 6. The tarball for the July 2010 release is available from http://github.com/rakudo/star/downloads.

Rakudo Star is aimed at "early adopters" of Perl 6. We know that it still has some bugs, it is far slower than it ought to be, and there are some advanced pieces of the Perl 6 language specification that aren't implemented yet. But Rakudo Perl 6 in its current form is also proving to be viable (and fun) for developing applications and exploring a great new language. These "Star" releases are intended to make Perl 6 more widely available to programmers, grow the Perl 6 codebase, and gain additional end-user feedback about the Perl 6 language and Rakudo's implementation of it.

In the Perl 6 world, we make a distinction between the language ("Perl 6") and specific implementations of the language such as "Rakudo Perl". "Rakudo Star" is a distribution that includes release #31 of the Rakudo Perl 6 "compiler, version 2.6.0 of the Parrot Virtual Machine, and various modules, documentation, and other resources collected from the Perl 6 community. We plan to make Rakudo Star releases on a monthly schedule, with occasional special releases in response to important bugfixes or changes.

Some of the many cool Perl 6 features that are available in this release of Rakudo Star:

  • Perl 6 grammars and regexes
  • formal parameter lists and signatures
  • metaoperators
  • gradual typing
  • a powerful object model, including roles and classes
  • lazy list evaluation
  • multiple dispatch
  • smart matching
  • junctions and autothreading
  • operator overloading (limited forms for now)
  • introspection
  • currying
  • a rich library of builtin operators, functions, and types
  • an interactive read-evaluation-print loop
  • Unicode at the codepoint level
  • resumable exceptions

There are some key features of Perl 6 that Rakudo Star does not yet handle appropriately, although they will appear in upcoming releases. Thus, we do not consider Rakudo Star to be a "Perl 6.0.0" or "1.0" release.

In many places we've tried to make Rakudo smart enough to inform the programmer that a given feature isn't implemented, but there are many that we've missed. Bug reports about missing and broken features are welcomed.

See http://perl6.org/ for links to much more information about Perl 6, including documentation, example code, tutorials, reference materials, specification documents, and other supporting resources. Rakudo Star also contains a draft of a Perl 6 book -- see in the release tarball.

The development team thanks all of the contributors and sponsors for making Rakudo Star possible. If you would like to contribute, see http://rakudo.org/how-to-help, ask on the perl6-compiler@perl.org mailing list, or join us on IRC #perl6 on freenode.

Rakudo Star releases are created on a monthly cycle or as needed in response to important bug fixes or improvements. The next planned release of Rakudo Star will be on August 24, 2010.

Editor's notes

For questions, contact Perl Foundation Public Relations at pr@perlfoundation.org.

Perl

Perl is a dynamic programming language created by Larry Wall and first released in 1987. Perl borrows features from a variety of other languages including C, shell scripting (sh), AWK, sed and Lisp. It is distributed with practically every version of Unix available and runs on a huge number of platforms, as diverse as Windows, Mac OS X, Solaris, z/OS, os400, QNX and Symbian.

The Perl Foundation

The Perl Foundation is dedicated to the advancement of the Perl programming language through open discussion, collaboration, design, and code. It is a non-profit, 501(c)(3) organization incorporated in Holland, Michigan, USA in 2000.

use Perl Journal Search: Stupid Lucene Tricks: Document Frequencies and NOT (2010.07.29 12:13)

Stupid Lucene Tricks: Document Frequencies and NOT (2010.07.29 12:13)
  1. You can get the document frequency of a term (i.e. how many documents have that term) through Lucene.Index.IndexReader.DocFreq(t As Term) As Integer.
  2. You can get the IndexReader for a Lucene.Search.IndexSearcher through IndexSearcher.GetIndexReader().
  3. If you want to display the document frequencies for the individual keywords of a search, and a piece is a NOT phrase (like -antibiotic in antimicrobial -antibiotic), you cannot use DocFreq() directly. In that case, the document frequency can be computed as:

          DOCFREQ = count of all documents - DocFreq(TERM_NO_NOT)

    as in:

          DOCFREQ = 60227 - DocFreq(New Term("all", "antibiotic"))

    where the NOT piece was -antibiotic and all is the Lucene document field in question.

(Ob. Perl: Although PLucene is now 5 years out of date, Perlesque should eventually let you get at Lucene.NET via a strongly-typed Perl 6.)

Planet Perl: Help?

(Before I begin, I should clarify I did not write this code, I'm just trying to maintain it)

The following error is the first thing spat out by make test for the Padre sync server, located at http://svn.perlide.org/padre/trunk/Madre-Sync.

Wasn't the move of Catalyst to Moose going to make things easier?

Can someone explain how you debug this?

I get the basics, I can see the "Can't locate Madre/Sync/Schema.pm". But that file should be, I think, automatically generated. And I don't really get how to dig down the 75 caller levels from the start to the end to work out where the actual functionality is failing...

not ok 1 - use Catalyst::Test;
 
#   Failed test 'use Catalyst::Test;'
#   at t\01app.t line 7.
#     Tried to use 'Catalyst::Test'.
#     Error:  Couldn't load class (Madre::Sync) because: Couldn't instantiate component "Madre::Sync::Model::padreDB", "Can't locate Madre/Sync/Schema.pm i
n @INC (@INC contains: blib\lib blib\arch C:/strawberry/perl/lib C:/strawberry/perl/site/lib C:\strawberry\perl\vendor\lib .). at C:\strawberry\perl\vendor
\lib/Class/MOP.pm line 132
#       Class::MOP::load_first_existing_class('Madre::Sync::Schema') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 137
#       Class::MOP::load_class('Madre::Sync::Schema') called at C:\strawberry\perl\vendor\lib/Catalyst/Model/DBIC/Schema/Types.pm line 21
#       Catalyst::Model::DBIC::Schema::Types::__ANON__[C:\strawberry\perl\vendor\lib/Ca talyst/Model/DBIC/Schema/Types.pm:21]('Madre::Sync::Schema') called
at C:\strawberry\perl\vendor\lib/Moose/Meta/TypeCoercion.pm line 63
#       Moose::Meta::TypeCoercion::__ANON__[C:\strawberry\perl\vendor\lib/Moose/Meta/Ty peCoercion.pm:67]('Madre::Sync::Schema') called at C:\strawberry\per
l\vendor\lib/Moose/Meta/TypeCoercion.pm line 97
#       Moose::Meta::TypeCoercion::coerce('Moose::Meta::TypeCoercion=HASH(0x4a2b444)', 'Madre::Sync::Schema') called at C:\strawberry\perl\vendor\lib/Moose
/Meta/TypeConstraint.pm line 90
#       Moose::Meta::TypeConstraint::coerce('Moose::Meta::TypeConstraint=HASH(0x4a29854 )', 'Madre::Sync::Schema') called at C:\strawberry\perl\vendor\lib/M
ooseX/Types/TypeDecorator.pm line 206
#       eval {...} called at C:\strawberry\perl\vendor\lib/MooseX/Types/TypeDecorator.pm line 205
#       MooseX::Types::TypeDecorator::AUTOLOAD('MooseX::Types::TypeDecorator=HASH(0x4a3 1424)', 'Madre::Sync::Schema') called at C:\strawberry\perl\vendor\l
ib/Moose/Meta/Attribute.pm line 743
#       Moose::Meta::Attribute::_coerce_and_verify('Moose::Meta::Attribute=HASH(0x4b467 fc)', 'Madre::Sync::Schema', 'Madre::Sync::Model::padreDB=HASH(0x4db
7c64)') called at C:\strawberry\perl\vendor\lib/Moose/Meta/Attribute.pm line 398
#       Moose::Meta::Attribute::initialize_instance_slot('Moose::Meta::Attribute=HASH(0 x4b467fc)', 'Moose::Meta::Instance=HASH(0x4db7ed4)', 'Madre::Sync::M
odel::padreDB=HASH(0x4db7c64)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Class/MOP/Class.pm line 567
#       Class::MOP::Class::_construct_instance('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Class/MOP/C
lass.pm line 540
#       Class::MOP::Class::new_object('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Moose/Meta/Class.pm
line 256
#       Moose::Meta::Class::new_object('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Moose/Object.pm lin
e 25
#       Moose::Object::new('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4b404ec)') called at generated method (unknown origin) line 4
#       Catalyst::Model::DBIC::Schema::new('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4b404ec)') called at C:\strawberry\perl\vendor\lib/MooseX/
Traits/Pluggable.pm line 131
#       MooseX::Traits::Pluggable::new_with_traits('Madre::Sync::Model::padreDB', 'Madre::Sync') called at C:\strawberry\perl\vendor\lib/CatalystX/Componen
t/Traits.pm line 146
#       CatalystX::Component::Traits::COMPONENT('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/Cl
ass/MOP/Method/Wrapped.pm line 48
#       Class::MOP::Method::Wrapped::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP/M ethod/Wrapped.pm:49]('Madre::Sync::Model::padreDB', 'Madre::Sync', '
HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/Class/MOP/Method/Wrapped.pm line 89
#       Catalyst::Model::DBIC::Schema::COMPONENT('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/C
atalyst.pm line 2502
#       eval {...} called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 2502
#       Catalyst::setup_component('Madre::Sync', 'Madre::Sync::Model::padreDB') called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 2416
#       Catalyst::setup_components('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Class/MOP/Method/Wrapped.pm line 54
#       Class::MOP::Method::Wrapped::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP/M ethod/Wrapped.pm:64]('Madre::Sync') called at C:\strawberry\perl\ven
dor\lib/Class/MOP/Method/Wrapped.pm line 89
#       Madre::Sync::setup_components('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 1142
#       Catalyst::setup('Madre::Sync') called at blib\lib/Madre/Sync.pm line 62
#       require Madre/Sync.pm called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 114
#       Class::MOP::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP.pm:118]() called at C:\strawberry\perl\vendor\lib/Try/Tiny.pm line 74
#       eval {...} called at C:\strawberry\perl\vendor\lib/Try/Tiny.pm line 67
#       Try::Tiny::try('CODE(0x36d759c)', 'Try::Tiny::Catch=REF(0x33a9584)') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 125
#       Class::MOP::load_first_existing_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 137
#       Class::MOP::load_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Catalyst/Test.pm line 24
#       Catalyst::Test::__ANON__[C:\strawberry\perl\vendor\lib/Catalyst/Test.pm:93]('Ca talyst::Test', 'all', 'HASH(0x36d768c)', 'HASH(0x25de3a4)') called a
t C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 493
#       Sub::Exporter::_expand_group('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d4994)', 'HASH(0x25de3a4)', 'HASH(0x36d755c)', 'HASH(0x25de334)') call
ed at C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 424
#       Sub::Exporter::_expand_groups('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d723c)', 'HASH(0x25de3a4)') called at C:\strawberry\perl\vendor\lib/S
ub/Exporter.pm line 742
#       Sub::Exporter::__ANON__[C:\strawberry\perl\vendor\lib/Sub/Exporter.pm:756]('Cat alyst::Test', '-all', 'HASH(0x36cc8d4)') called at C:\strawberry\per
l\vendor\lib/Catalyst/Test.pm line 112
#       Catalyst::Test::import('Catalyst::Test', 'Madre::Sync') called at (eval 11)[C:/strawberry/perl/lib/Test/More.pm:858] line 2
#       main::BEGIN() called at blib\lib/Madre/Sync.pm line 0
#       eval {...} called at blib\lib/Madre/Sync.pm line 0
#       eval 'package main;
# use Catalyst::Test @{$args[0]};
# 1;
#
# ;' called at C:/strawberry/perl/lib/Test/More.pm line 858
#       Test::More::_eval('package main;\x{a}use Catalyst::Test @{$args[0]};\x{a}1;\x{a}', 'ARRAY(0x2308474)') called at C:/strawberry/perl/lib/Test/More.p
m line 833
#       Test::More::use_ok('Catalyst::Test', 'Madre::Sync') called at t\01app.t line 7
#  at C:\strawberry\perl\vendor\lib/MooseX/Types/TypeDecorator.pm line 208
#       MooseX::Types::TypeDecorator::AUTOLOAD('MooseX::Types::TypeDecorator=HASH(0x4a3 1424)', 'Madre::Sync::Schema') called at C:\strawberry\perl\vendor\l
ib/Moose/Meta/Attribute.pm line 743
#       Moose::Meta::Attribute::_coerce_and_verify('Moose::Meta::Attribute=HASH(0x4b467 fc)', 'Madre::Sync::Schema', 'Madre::Sync::Model::padreDB=HASH(0x4db
7c64)') called at C:\strawberry\perl\vendor\lib/Moose/Meta/Attribute.pm line 398
#       Moose::Meta::Attribute::initialize_instance_slot('Moose::Meta::Attribute=HASH(0 x4b467fc)', 'Moose::Meta::Instance=HASH(0x4db7ed4)', 'Madre::Sync::M
odel::padreDB=HASH(0x4db7c64)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Class/MOP/Class.pm line 567
#       Class::MOP::Class::_construct_instance('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Class/MOP/C
lass.pm line 540
#       Class::MOP::Class::new_object('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Moose/Meta/Class.pm
line 256
#       Moose::Meta::Class::new_object('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Moose/Object.pm lin
e 25
#       Moose::Object::new('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4b404ec)') called at generated method (unknown origin) line 4
#       Catalyst::Model::DBIC::Schema::new('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4b404ec)') called at C:\strawberry\perl\vendor\lib/MooseX/
Traits/Pluggable.pm line 131
#       MooseX::Traits::Pluggable::new_with_traits('Madre::Sync::Model::padreDB', 'Madre::Sync') called at C:\strawberry\perl\vendor\lib/CatalystX/Componen
t/Traits.pm line 146
#       CatalystX::Component::Traits::COMPONENT('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/Cl
ass/MOP/Method/Wrapped.pm line 48
#       Class::MOP::Method::Wrapped::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP/M ethod/Wrapped.pm:49]('Madre::Sync::Model::padreDB', 'Madre::Sync', '
HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/Class/MOP/Method/Wrapped.pm line 89
#       Catalyst::Model::DBIC::Schema::COMPONENT('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/C
atalyst.pm line 2502
#       eval {...} called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 2502
#       Catalyst::setup_component('Madre::Sync', 'Madre::Sync::Model::padreDB') called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 2416
#       Catalyst::setup_components('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Class/MOP/Method/Wrapped.pm line 54
#       Class::MOP::Method::Wrapped::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP/M ethod/Wrapped.pm:64]('Madre::Sync') called at C:\strawberry\perl\ven
dor\lib/Class/MOP/Method/Wrapped.pm line 89
#       Madre::Sync::setup_components('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 1142
#       Catalyst::setup('Madre::Sync') called at blib\lib/Madre/Sync.pm line 62
#       require Madre/Sync.pm called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 114
#       Class::MOP::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP.pm:118]() called at C:\strawberry\perl\vendor\lib/Try/Tiny.pm line 74
#       eval {...} called at C:\strawberry\perl\vendor\lib/Try/Tiny.pm line 67
#       Try::Tiny::try('CODE(0x36d759c)', 'Try::Tiny::Catch=REF(0x33a9584)') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 125
#       Class::MOP::load_first_existing_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 137
#       Class::MOP::load_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Catalyst/Test.pm line 24
#       Catalyst::Test::__ANON__[C:\strawberry\perl\vendor\lib/Catalyst/Test.pm:93]('Ca talyst::Test', 'all', 'HASH(0x36d768c)', 'HASH(0x25de3a4)') called a
t C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 493
#       Sub::Exporter::_expand_group('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d4994)', 'HASH(0x25de3a4)', 'HASH(0x36d755c)', 'HASH(0x25de334)') call
ed at C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 424
#       Sub::Exporter::_expand_groups('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d723c)', 'HASH(0x25de3a4)') called at C:\strawberry\perl\vendor\lib/S
ub/Exporter.pm line 742
#       Sub::Exporter::__ANON__[C:\strawberry\perl\vendor\lib/Sub/Exporter.pm:756]('Cat alyst::Test', '-all', 'HASH(0x36cc8d4)') called at C:\strawberry\per
l\vendor\lib/Catalyst/Test.pm line 112
#       Catalyst::Test::import('Catalyst::Test', 'Madre::Sync') called at (eval 11)[C:/strawberry/perl/lib/Test/More.pm:858] line 2
#       main::BEGIN() called at blib\lib/Madre/Sync.pm line 0
#       eval {...} called at blib\lib/Madre/Sync.pm line 0
#       eval 'package main;
# use Catalyst::Test @{$args[0]};
# 1;
#
# ;' called at C:/strawberry/perl/lib/Test/More.pm line 858
#       Test::More::_eval('package main;\x{a}use Catalyst::Test @{$args[0]};\x{a}1;\x{a}', 'ARRAY(0x2308474)') called at C:/strawberry/perl/lib/Test/More.p
m line 833
#       Test::More::use_ok('Catalyst::Test', 'Madre::Sync') called at t\01app.t line 7"Compilation failed in require at C:\strawberry\perl\vendor\lib/Class
/MOP.pm line 114.
#  at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 121
#       Class::MOP::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP.pm:125]('Couldn\'t instantiate component "Madre::Sync::Model::padreDB"...') called at
C:\strawberry\perl\vendor\lib/Try/Tiny.pm line 98
#       Try::Tiny::try('CODE(0x36d759c)', 'Try::Tiny::Catch=REF(0x33a9584)') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 125
#       Class::MOP::load_first_existing_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 137
#       Class::MOP::load_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Catalyst/Test.pm line 24
#       Catalyst::Test::__ANON__[C:\strawberry\perl\vendor\lib/Catalyst/Test.pm:93]('Ca talyst::Test', 'all', 'HASH(0x36d768c)', 'HASH(0x25de3a4)') called a
t C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 493
#       Sub::Exporter::_expand_group('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d4994)', 'HASH(0x25de3a4)', 'HASH(0x36d755c)', 'HASH(0x25de334)') call
ed at C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 424
#       Sub::Exporter::_expand_groups('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d723c)', 'HASH(0x25de3a4)') called at C:\strawberry\perl\vendor\lib/S
ub/Exporter.pm line 742
#       Sub::Exporter::__ANON__[C:\strawberry\perl\vendor\lib/Sub/Exporter.pm:756]('Cat alyst::Test', '-all', 'HASH(0x36cc8d4)') called at C:\strawberry\per
l\vendor\lib/Catalyst/Test.pm line 112
#       Catalyst::Test::import('Catalyst::Test', 'Madre::Sync') called at (eval 11)[C:/strawberry/perl/lib/Test/More.pm:858] line 2
#       main::BEGIN() called at C:\strawberry\perl\vendor\lib/Catalyst/Test.pm line 2
#       eval {...} called at C:\strawberry\perl\vendor\lib/Catalyst/Test.pm line 2
#       eval 'package main;
# use Catalyst::Test @{$args[0]};
# 1;
#
# ;' called at C:/strawberry/perl/lib/Test/More.pm line 858
#       Test::More::_eval('package main;\x{a}use Catalyst::Test @{$args[0]};\x{a}1;\x{a}', 'ARRAY(0x2308474)') called at C:/strawberry/perl/lib/Test/More.p
m line 833
#       Test::More::use_ok('Catalyst::Test', 'Madre::Sync') called at t\01app.t line 7
# BEGIN failed--compilation aborted at (eval 11)[C:/strawberry/perl/lib/Test/More.pm:858] line 2.

use Perl Journal Search: Help? (2010.07.29 9:23)

Help? (2010.07.29  9:23)

(Before I begin, I should clarify I did not write this code, I'm just trying to maintain it)

The following error is the first thing spat out by make test for the Padre sync server, located at http://svn.perlide.org/padre/trunk/Madre-Sync.

Wasn't the move of Catalyst to Moose going to make things easier?

Can someone explain how you debug this?

I get the basics, I can see the "Can't locate Madre/Sync/Schema.pm". But that file should be, I think, automatically generated. And I don't really get how to dig down the 75 caller levels from the start to the end to work out where the actual functionality is failing...

not ok 1 - use Catalyst::Test;
 
#   Failed test 'use Catalyst::Test;'
#   at t\01app.t line 7.
#     Tried to use 'Catalyst::Test'.
#     Error:  Couldn't load class (Madre::Sync) because: Couldn't instantiate component "Madre::Sync::Model::padreDB", "Can't locate Madre/Sync/Schema.pm i
n @INC (@INC contains: blib\lib blib\arch C:/strawberry/perl/lib C:/strawberry/perl/site/lib C:\strawberry\perl\vendor\lib .). at C:\strawberry\perl\vendor
\lib/Class/MOP.pm line 132
#       Class::MOP::load_first_existing_class('Madre::Sync::Schema') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 137
#       Class::MOP::load_class('Madre::Sync::Schema') called at C:\strawberry\perl\vendor\lib/Catalyst/Model/DBIC/Schema/Types.pm line 21
#       Catalyst::Model::DBIC::Schema::Types::__ANON__[C:\strawberry\perl\vendor\lib/Ca talyst/Model/DBIC/Schema/Types.pm:21]('Madre::Sync::Schema') called
at C:\strawberry\perl\vendor\lib/Moose/Meta/TypeCoercion.pm line 63
#       Moose::Meta::TypeCoercion::__ANON__[C:\strawberry\perl\vendor\lib/Moose/Meta/Ty peCoercion.pm:67]('Madre::Sync::Schema') called at C:\strawberry\per
l\vendor\lib/Moose/Meta/TypeCoercion.pm line 97
#       Moose::Meta::TypeCoercion::coerce('Moose::Meta::TypeCoercion=HASH(0x4a2b444)', 'Madre::Sync::Schema') called at C:\strawberry\perl\vendor\lib/Moose
/Meta/TypeConstraint.pm line 90
#       Moose::Meta::TypeConstraint::coerce('Moose::Meta::TypeConstraint=HASH(0x4a29854 )', 'Madre::Sync::Schema') called at C:\strawberry\perl\vendor\lib/M
ooseX/Types/TypeDecorator.pm line 206
#       eval {...} called at C:\strawberry\perl\vendor\lib/MooseX/Types/TypeDecorator.pm line 205
#       MooseX::Types::TypeDecorator::AUTOLOAD('MooseX::Types::TypeDecorator=HASH(0x4a3 1424)', 'Madre::Sync::Schema') called at C:\strawberry\perl\vendor\l
ib/Moose/Meta/Attribute.pm line 743
#       Moose::Meta::Attribute::_coerce_and_verify('Moose::Meta::Attribute=HASH(0x4b467 fc)', 'Madre::Sync::Schema', 'Madre::Sync::Model::padreDB=HASH(0x4db
7c64)') called at C:\strawberry\perl\vendor\lib/Moose/Meta/Attribute.pm line 398
#       Moose::Meta::Attribute::initialize_instance_slot('Moose::Meta::Attribute=HASH(0 x4b467fc)', 'Moose::Meta::Instance=HASH(0x4db7ed4)', 'Madre::Sync::M
odel::padreDB=HASH(0x4db7c64)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Class/MOP/Class.pm line 567
#       Class::MOP::Class::_construct_instance('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Class/MOP/C
lass.pm line 540
#       Class::MOP::Class::new_object('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Moose/Meta/Class.pm
line 256
#       Moose::Meta::Class::new_object('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Moose/Object.pm lin
e 25
#       Moose::Object::new('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4b404ec)') called at generated method (unknown origin) line 4
#       Catalyst::Model::DBIC::Schema::new('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4b404ec)') called at C:\strawberry\perl\vendor\lib/MooseX/
Traits/Pluggable.pm line 131
#       MooseX::Traits::Pluggable::new_with_traits('Madre::Sync::Model::padreDB', 'Madre::Sync') called at C:\strawberry\perl\vendor\lib/CatalystX/Componen
t/Traits.pm line 146
#       CatalystX::Component::Traits::COMPONENT('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/Cl
ass/MOP/Method/Wrapped.pm line 48
#       Class::MOP::Method::Wrapped::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP/M ethod/Wrapped.pm:49]('Madre::Sync::Model::padreDB', 'Madre::Sync', '
HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/Class/MOP/Method/Wrapped.pm line 89
#       Catalyst::Model::DBIC::Schema::COMPONENT('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/C
atalyst.pm line 2502
#       eval {...} called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 2502
#       Catalyst::setup_component('Madre::Sync', 'Madre::Sync::Model::padreDB') called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 2416
#       Catalyst::setup_components('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Class/MOP/Method/Wrapped.pm line 54
#       Class::MOP::Method::Wrapped::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP/M ethod/Wrapped.pm:64]('Madre::Sync') called at C:\strawberry\perl\ven
dor\lib/Class/MOP/Method/Wrapped.pm line 89
#       Madre::Sync::setup_components('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 1142
#       Catalyst::setup('Madre::Sync') called at blib\lib/Madre/Sync.pm line 62
#       require Madre/Sync.pm called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 114
#       Class::MOP::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP.pm:118]() called at C:\strawberry\perl\vendor\lib/Try/Tiny.pm line 74
#       eval {...} called at C:\strawberry\perl\vendor\lib/Try/Tiny.pm line 67
#       Try::Tiny::try('CODE(0x36d759c)', 'Try::Tiny::Catch=REF(0x33a9584)') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 125
#       Class::MOP::load_first_existing_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 137
#       Class::MOP::load_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Catalyst/Test.pm line 24
#       Catalyst::Test::__ANON__[C:\strawberry\perl\vendor\lib/Catalyst/Test.pm:93]('Ca talyst::Test', 'all', 'HASH(0x36d768c)', 'HASH(0x25de3a4)') called a
t C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 493
#       Sub::Exporter::_expand_group('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d4994)', 'HASH(0x25de3a4)', 'HASH(0x36d755c)', 'HASH(0x25de334)') call
ed at C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 424
#       Sub::Exporter::_expand_groups('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d723c)', 'HASH(0x25de3a4)') called at C:\strawberry\perl\vendor\lib/S
ub/Exporter.pm line 742
#       Sub::Exporter::__ANON__[C:\strawberry\perl\vendor\lib/Sub/Exporter.pm:756]('Cat alyst::Test', '-all', 'HASH(0x36cc8d4)') called at C:\strawberry\per
l\vendor\lib/Catalyst/Test.pm line 112
#       Catalyst::Test::import('Catalyst::Test', 'Madre::Sync') called at (eval 11)[C:/strawberry/perl/lib/Test/More.pm:858] line 2
#       main::BEGIN() called at blib\lib/Madre/Sync.pm line 0
#       eval {...} called at blib\lib/Madre/Sync.pm line 0
#       eval 'package main;
# use Catalyst::Test @{$args[0]};
# 1;
#
# ;' called at C:/strawberry/perl/lib/Test/More.pm line 858
#       Test::More::_eval('package main;\x{a}use Catalyst::Test @{$args[0]};\x{a}1;\x{a}', 'ARRAY(0x2308474)') called at C:/strawberry/perl/lib/Test/More.p
m line 833
#       Test::More::use_ok('Catalyst::Test', 'Madre::Sync') called at t\01app.t line 7
#  at C:\strawberry\perl\vendor\lib/MooseX/Types/TypeDecorator.pm line 208
#       MooseX::Types::TypeDecorator::AUTOLOAD('MooseX::Types::TypeDecorator=HASH(0x4a3 1424)', 'Madre::Sync::Schema') called at C:\strawberry\perl\vendor\l
ib/Moose/Meta/Attribute.pm line 743
#       Moose::Meta::Attribute::_coerce_and_verify('Moose::Meta::Attribute=HASH(0x4b467 fc)', 'Madre::Sync::Schema', 'Madre::Sync::Model::padreDB=HASH(0x4db
7c64)') called at C:\strawberry\perl\vendor\lib/Moose/Meta/Attribute.pm line 398
#       Moose::Meta::Attribute::initialize_instance_slot('Moose::Meta::Attribute=HASH(0 x4b467fc)', 'Moose::Meta::Instance=HASH(0x4db7ed4)', 'Madre::Sync::M
odel::padreDB=HASH(0x4db7c64)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Class/MOP/Class.pm line 567
#       Class::MOP::Class::_construct_instance('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Class/MOP/C
lass.pm line 540
#       Class::MOP::Class::new_object('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Moose/Meta/Class.pm
line 256
#       Moose::Meta::Class::new_object('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Moose/Object.pm lin
e 25
#       Moose::Object::new('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4b404ec)') called at generated method (unknown origin) line 4
#       Catalyst::Model::DBIC::Schema::new('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4b404ec)') called at C:\strawberry\perl\vendor\lib/MooseX/
Traits/Pluggable.pm line 131
#       MooseX::Traits::Pluggable::new_with_traits('Madre::Sync::Model::padreDB', 'Madre::Sync') called at C:\strawberry\perl\vendor\lib/CatalystX/Componen
t/Traits.pm line 146
#       CatalystX::Component::Traits::COMPONENT('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/Cl
ass/MOP/Method/Wrapped.pm line 48
#       Class::MOP::Method::Wrapped::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP/M ethod/Wrapped.pm:49]('Madre::Sync::Model::padreDB', 'Madre::Sync', '
HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/Class/MOP/Method/Wrapped.pm line 89
#       Catalyst::Model::DBIC::Schema::COMPONENT('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/C
atalyst.pm line 2502
#       eval {...} called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 2502
#       Catalyst::setup_component('Madre::Sync', 'Madre::Sync::Model::padreDB') called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 2416
#       Catalyst::setup_components('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Class/MOP/Method/Wrapped.pm line 54
#       Class::MOP::Method::Wrapped::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP/M ethod/Wrapped.pm:64]('Madre::Sync') called at C:\strawberry\perl\ven
dor\lib/Class/MOP/Method/Wrapped.pm line 89
#       Madre::Sync::setup_components('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 1142
#       Catalyst::setup('Madre::Sync') called at blib\lib/Madre/Sync.pm line 62
#       require Madre/Sync.pm called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 114
#       Class::MOP::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP.pm:118]() called at C:\strawberry\perl\vendor\lib/Try/Tiny.pm line 74
#       eval {...} called at C:\strawberry\perl\vendor\lib/Try/Tiny.pm line 67
#       Try::Tiny::try('CODE(0x36d759c)', 'Try::Tiny::Catch=REF(0x33a9584)') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 125
#       Class::MOP::load_first_existing_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 137
#       Class::MOP::load_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Catalyst/Test.pm line 24
#       Catalyst::Test::__ANON__[C:\strawberry\perl\vendor\lib/Catalyst/Test.pm:93]('Ca talyst::Test', 'all', 'HASH(0x36d768c)', 'HASH(0x25de3a4)') called a
t C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 493
#       Sub::Exporter::_expand_group('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d4994)', 'HASH(0x25de3a4)', 'HASH(0x36d755c)', 'HASH(0x25de334)') call
ed at C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 424
#       Sub::Exporter::_expand_groups('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d723c)', 'HASH(0x25de3a4)') called at C:\strawberry\perl\vendor\lib/S
ub/Exporter.pm line 742
#       Sub::Exporter::__ANON__[C:\strawberry\perl\vendor\lib/Sub/Exporter.pm:756]('Cat alyst::Test', '-all', 'HASH(0x36cc8d4)') called at C:\strawberry\per
l\vendor\lib/Catalyst/Test.pm line 112
#       Catalyst::Test::import('Catalyst::Test', 'Madre::Sync') called at (eval 11)[C:/strawberry/perl/lib/Test/More.pm:858] line 2
#       main::BEGIN() called at blib\lib/Madre/Sync.pm line 0
#       eval {...} called at blib\lib/Madre/Sync.pm line 0
#       eval 'package main;
# use Catalyst::Test @{$args[0]};
# 1;
#
# ;' called at C:/strawberry/perl/lib/Test/More.pm line 858
#       Test::More::_eval('package main;\x{a}use Catalyst::Test @{$args[0]};\x{a}1;\x{a}', 'ARRAY(0x2308474)') called at C:/strawberry/perl/lib/Test/More.p
m line 833
#       Test::More::use_ok('Catalyst::Test', 'Madre::Sync') called at t\01app.t line 7"Compilation failed in require at C:\strawberry\perl\vendor\lib/Class
/MOP.pm line 114.
#  at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 121
#       Class::MOP::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP.pm:125]('Couldn\'t instantiate component "Madre::Sync::Model::padreDB"...') called at
C:\strawberry\perl\vendor\lib/Try/Tiny.pm line 98
#       Try::Tiny::try('CODE(0x36d759c)', 'Try::Tiny::Catch=REF(0x33a9584)') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 125
#       Class::MOP::load_first_existing_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 137
#       Class::MOP::load_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Catalyst/Test.pm line 24
#       Catalyst::Test::__ANON__[C:\strawberry\perl\vendor\lib/Catalyst/Test.pm:93]('Ca talyst::Test', 'all', 'HASH(0x36d768c)', 'HASH(0x25de3a4)') called a
t C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 493
#       Sub::Exporter::_expand_group('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d4994)', 'HASH(0x25de3a4)', 'HASH(0x36d755c)', 'HASH(0x25de334)') call
ed at C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 424
#       Sub::Exporter::_expand_groups('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d723c)', 'HASH(0x25de3a4)') called at C:\strawberry\perl\vendor\lib/S
ub/Exporter.pm line 742
#       Sub::Exporter::__ANON__[C:\strawberry\perl\vendor\lib/Sub/Exporter.pm:756]('Cat alyst::Test', '-all', 'HASH(0x36cc8d4)') called at C:\strawberry\per
l\vendor\lib/Catalyst/Test.pm line 112
#       Catalyst::Test::import('Catalyst::Test', 'Madre::Sync') called at (eval 11)[C:/strawberry/perl/lib/Test/More.pm:858] line 2
#       main::BEGIN() called at C:\strawberry\perl\vendor\lib/Catalyst/Test.pm line 2
#       eval {...} called at C:\strawberry\perl\vendor\lib/Catalyst/Test.pm line 2
#       eval 'package main;
# use Catalyst::Test @{$args[0]};
# 1;
#
# ;' called at C:/strawberry/perl/lib/Test/More.pm line 858
#       Test::More::_eval('package main;\x{a}use Catalyst::Test @{$args[0]};\x{a}1;\x{a}', 'ARRAY(0x2308474)') called at C:/strawberry/perl/lib/Test/More.p
m line 833
#       Test::More::use_ok('Catalyst::Test', 'Madre::Sync') called at t\01app.t line 7
# BEGIN failed--compilation aborted at (eval 11)[C:/strawberry/perl/lib/Test/More.pm:858] line 2.

use Perl Journal Search: Rakudo Star - an "early adopter" distribution of Perl 6 (2010.07.29 8:28)

Rakudo Star - an "early adopter" distribution of Perl 6 (2010.07.29  8:28)

On behalf of the Rakudo and Perl 6 development teams, I'm happy to announce the July 2010 release of "Rakudo Star", a useful and usable distribution of Perl 6. The tarball for the July 2010 release is available from http://github.com/rakudo/star/downloads.

Rakudo Star is aimed at "early adopters" of Perl 6. We know that it still has some bugs, it is far slower than it ought to be, and there are some advanced pieces of the Perl 6 language specification that aren't implemented yet. But Rakudo Perl 6 in its current form is also proving to be viable (and fun) for developing applications and exploring a great new language. These "Star" releases are intended to make Perl 6 more widely available to programmers, grow the Perl 6 codebase, and gain additional end-user feedback about the Perl 6 language and Rakudo's implementation of it.

In the Perl 6 world, we make a distinction between the language ("Perl 6") and specific implementations of the language such as "Rakudo Perl". "Rakudo Star" is a distribution that includes release #31 of the Rakudo Perl 6 compiler [1], version 2.6.0 of the Parrot Virtual Machine [2], and various modules, documentation, and other resources collected from the Perl 6 community. We plan to make Rakudo Star releases on a monthly schedule, with occasional special releases in response to important bugfixes or changes.

Some of the many cool Perl 6 features that are available in this release of Rakudo Star:

  • Perl 6 grammars and regexes
  • formal parameter lists and signatures
  • metaoperators
  • gradual typing
  • a powerful object model, including roles and classes
  • lazy list evaluation
  • multiple dispatch
  • smart matching
  • junctions and autothreading
  • operator overloading (limited forms for now)
  • introspection
  • currying
  • a rich library of builtin operators, functions, and types
  • an interactive read-evaluation-print loop
  • Unicode at the codepoint level
  • resumable exceptions

There are some key features of Perl 6 that Rakudo Star does not yet handle appropriately, although they will appear in upcoming releases. Thus, we do not consider Rakudo Star to be a "Perl 6.0.0" or "1.0" release. Some of the not-quite-there features include:

  • nested package definitions
  • binary objects, native types, pack and unpack
  • typed arrays
  • macros
  • state variables
  • threads and concurrency
  • Unicode strings at levels other than codepoints
  • pre and post constraints, and some other phasers
  • interactive readline that understands Unicode
  • backslash escapes in regex <[...]> character classes
  • non-blocking I/O
  • most of Synopsis 9
  • perl6doc or pod manipulation tools

In many places we've tried to make Rakudo smart enough to inform the programmer that a given feature isn't implemented, but there are many that we've missed. Bug reports about missing and broken features are welcomed.

See http://perl6.org/ for links to much more information about Perl 6, including documentation, example code, tutorials, reference materials, specification documents, and other supporting resources.

Rakudo Star also bundles a number of modules; a partial list of the modules provided by this release include:

  • Blizkost - enables some Perl 5 modules to be used from within Rakudo Perl 6
  • MiniDBI - a simple database interface for Rakudo Perl 6
  • Zavolaj - call C library functions from Rakudo Perl 6
  • SVG and SVG::Plot - create scalable vector graphics
  • HTTP::Daemon - a simple HTTP server
  • XML::Writer - generate XML
  • YAML - dump Perl 6 objects as YAML
  • Term::ANSIColor - color screen output using ANSI escape sequences
  • Test::Mock - create mock objects and check what methods were called
  • Math::Model - describe and run mathematical models
  • Config::INI - parse and write configuration files
  • File::Find - find files in a given directory
  • LWP::Simple - fetch resources from the web

These are not considered "core Perl 6 modules", and as module development for Perl 6 continues to mature, future releases of Rakudo Star will likely come bundled with a different set of modules. Deprecation policies for bundled modules will be created over time, and other Perl 6 distributions may choose different sets of modules or policies. More information about Perl 6 modules can be found at http://modules.perl6.org.

Rakudo Star also contains a draft of a Perl 6 book -- see "docs/UsingPerl6-draft.pdf" in the release tarball.

The development team thanks all of the contributors and sponsors for making Rakudo Star possible. If you would like to contribute, see http://rakudo.org/how-to-help, ask on the perl6-compiler@perl.org mailing list, or join us on IRC #perl6 on freenode.

Rakudo Star releases are created on a monthly cycle or as needed in response to important bug fixes or improvements. The next planned release of Rakudo Star will be on August 24, 2010.

[1] http://github.com/rakudo/rakudo
[2] http://parrot.org/

Perl is Alive: Kephra 0.4.3 released

Kephra (http://search.cpan.org/dist/Kephra/lib/Kephra.pm), the editor written in Perl, has reached its first version that is UTF-safe and installable via CPAN. The all in one package for Windows users is still available under http://kephra.sf.net/ (http://kephra.sf.net/)

Perlsphere: perl's state in mandriva cooker

some time after <a href="http://www.mandriva.com/">mandriva</a> 2010.1 has been released, i'm now pleased to report that <a href="http://www.perl.org/">perl</a> has been updated to 5.12.1, all <a href="http://search.cpan.org/">cpan</a> modules are up-to-date (including padre 0.68) or bugs have been reported upstream... and parrot 2.6.0 is currently building.<br /><br />the perl 5.12.0 - 5.12.1 upgrade was really smooth: no patch to rediff, reapply, etc. that's definitely a good thing for perl maintainers to have a stable series with only critical fixes going in. i've already <a href="http://perldoc.perl.org/5.12.1/perlthanks.html">said it</a>, but thanks again to p5p!<div class="blogger-post-footer"><img alt=""></div>

Perlsphere: Does Your Perl Suck if You Don’t Use Moose?

chromatic says that using Moose or a similar abstraction mechanism is an important indicator of Perl ability.

Pshaw.

I’m a 6th level Perlic User. I’m quite capable of constructing my own objects1 thanks very much.

This is chromatic:

Here’s a quick checklist to help those of you writing Perl to determine if you’re capable of writing Perl well:

  • Do you do this?
  • Do you do that?
  • Do you use Moose or another abstraction mechanism from the CPAN?

Okay you got me. I’m quoting out of context. Here’s chromatic again:

You don’t have to answer all of those questions in the correct way to write good and maintainable Perl, but if you answer most of those questions in the wrong way, of course you’ll write bad code.

I don’t know what these 18 items actually indicate, how well integrated you are with the perlective perhaps or how much you code like chromatic, but for sure only 6 or 7 at best are decent indicators of ability to write Perl well. I answered 9 of them in the wrong way and I’m certainly not rushing to correct the deficiency.


1. Having said that, I have used Moose before, and for the right project, I would use it again.


Filed under: Perl Tagged: moose, outspoken

Planet Perl: java2perl6api – Java to Perl 6 API translation – What, Why, and Whereto

In this post I’m going to talk about the java2perl6api project. What its goals are, why I think it’s important, how it relates to a Perl 6 DBI, what exists now, what’s needs doing, and how you can help.

Firstly I’d like to point out that, funnily enough, I’m not very familiar with Java or Perl6. It’s entirely possible that I’ll make all sorts of errors in the following details. If you spot any do please let me know.

Background

The Java language ecosystem is big and mature after years of heavy investment of time and money.

It doesn’t have a central repository of Open Source modules like CPAN (though Maven repositories like these are similar I guess). It does, however, have a number of mature high quality class libraries, and a very large number of developers familiar with those libraries (more on that below).

Goals

The primary goal of the java2perl6api project is to make it easy to create Perl 6 class libraries that mirror Java equivalents. By mirror I mean share the same method names and semantics at a high level (though not at a low-level, more on that below).

Secondary goals are to do that well enough that:

  • the documentation for Java classes can serve as primary the documentation for the corresponding Perl 6 classes. The Perl 6 classes need only document the differences in behavior, which these should be minimal and ‘natural’. The same applies to books describing the Java classes.
  • Java developers familiar with the Java classes should feel comfortable working with the corresponding Perl 6 classes.
  • and, hopefully, some way can be found to convert test suites for the Java classes into Perl 6 code that’ll test the corresponding Perl 6 classes. (I appreciate that this is a non-trivial proposition, but there are viable approaches available, like xmlvm.) Even if that can’t be done, extracting and translating tests manually is less work, and more effective, than creating them from scratch for a new API.

Why?

Firstly, creating good APIs is hard. Java APIs like JDBC 3.0 and NIO.2 are the result of years of professional effort and demanding commercial experience. Why not build on that experience?

I appreciate that Java APIs are often limited by the constraints of the language, such as the lack of closures, and that Perl 6 can probably express any given set of semantics more effectively than Java. My point here is that some Java APIs embody, however inelegantly, years of hard won experience that we can benefit from. I’d rather make new mistakes than repeat old ones.

Secondly, there are many more Java developers than Perl developers. Many many more if job vacancies are any indication:

job vacancy trends for perl developer and java developer

I think we’d be foolish not to try to smooth the path for any Java developers who might be interested in Perl 6. The java2perl6api project is just one small aspect of that.

I really hope someone starts writing a “Perl 6 for Java Developers” tutorial. Perl 6 has the potential to become a very popular language1. Getting just a tiny percentage of Java developers (and Computer Science majors and their teachers) interested in it could be a big help.

Thirdly, any future DBI for Perl 6 and Parrot needs a much better foundation than the very limited and poorly defined one that underlies the Perl 5 DBI. I plan to adopt the JDBC 3.0 API and test suite for that internal role. (You could call this a “Test Suite Driven Strategy”.) I’ll talk more about that in a future blog post.

The History java2perl6api

I’ve been kicking around various ideas for integrating Java and Perl6/Parrot for years. I think I first decided to use JDBC as the inspiration for the DBI-to-driver API in 2006.

You may remember back in 2004, around the 10th anniversary of the DBI, the Perl Foundation setup a “DBI Development Fund” that people could donate to. I’ve never drawn any money from that fund. I want to use it to oil other peoples wheels.

In 2007 Best Practical sponsored Perl 6 Microgrants through the Perl Foundation. I asked if I could piggyback my idea for a Java to Perl 6 API translator onto their microgrant management process but using money from the DBI Development Fund. TPF and Best Practical kindly agreed. I posted a description of the task and Phil Crow volunteered and was awarded the microgrant in April 2007.

At OSCON in July 2007 I gave lightning talk called “Database interfaces for open source languages suck” which explained the rationale for using JDBC as a foundation for the DBI-to-driver API and mentioned Phil’s java2perl6 project.

Development ground to a halt around the end of 2007 for various reasons. It picked up again for a few months after OSCON 2009 (where I gave a short lightning talk asking for help) then stalled again in October. Partly because we seemed to have hit a limitation with Rakudo and partly because I was focussed on Devel::NYTProf version 3 and then version 4, which took way more time than I expected.

There’s life in the project again now. We’ve dodged the earlier problem, put the code on github, brought it into sync with current Rakudo Perl 6 syntax, and generally instilled some momentum.

The Current java2perl6api

Let’s take a look at a simple example.

To generate a perl6 file that mirrors the API of the java.sql.Savepoint class you’d just execute java2perl6api like this:

$ java2perl6api java.sql.Savepoint
loading java.sql.Savepoint
wrote java/sql/Savepoint.pm6 - interface java.sql.Savepoint
checking java/sql/Savepoint.pm6 - interface java.sql.Savepoint

That’s loaded and parsed the description of the java.sql.Savepoint class (from the javap command), generated a corresponding perl6 module, and run perl6 to validate it.

The generated module (with some whitespace and cruft removed) looks like this:

use v6;
role java::sql::Savepoint {
    method getSavepointId (
    --> Int   #  int
    ) { ... }
    method getSavepointName (
    --> Str   #  java.lang.String
    ) { ... }
};
=begin pod
=head1 Java
  Compiled from "Savepoint.java"
  public interface java.sql.Savepoint{
      public abstract int getSavepointId() throws java.sql.SQLException;
      public abstract java.lang.String getSavepointName() throws java.sql.SQLException;
  }
=end pod

The pod section shows the description of the class that javap returned. The java2perl6api utility parsed that Java interface and generated the corresponding Perl6 role. The ‘java.sql.Savepoint’ has been mapped to ‘java::sql::Savepoint’. The generated methods are stubs using ... (the “yada, yada, yada” operator). The types int and java.lang.String have been mapped to Int and Str. Because the only types used were built-ins, no type declarations were added.

Currently java2perl6api handles the above plus overloaded methods (which generate multi methods), multiple implements clauses (which generate multiple does clauses). There’s also partial support for class/interface constants (which currently generate exported methods).

The default behavior is to recursively process any Java types referenced by the class which aren’t mapped to Perl 6 types. So executing java2perl6api java.sql.Connection, for example, will generate 48 Perl 6 modules! (Because java.sql.Connection refers to many types, including java.sql.Array which refers to many types including java.sql.ResultSet which refers to java.net.URL which refers to java.net.Proxy etc. etc.) The --norecurse options disables this behavior.

Normally you’ll want to use the recursion but instead of letting it drill all the way into the Java types, you would supply your own ‘typemap’ specification via an option. That tells java2perl6api which Java types you want to map to which Perl 6 types. So instead of recursing into the java.net.URL type to generate a java/net/URL.pm6 file, for example, you can tell java2perl6api to use a specific Perl 6 type. Perhaps just Str for now.

How this relates to JDBC / DBDI / DBI v2

I want to start applying java2perl6api to the JDBC classes now to create a “Database Driver Interface” or “DBDI” for Perl 6.

Starting with the DriverManager class and the Connection interface I’ll use java2perl6api to generate corresponding Perl 6 roles with heavy stubbing out of types. Basically anything I don’t need to think about right now will be mapped to the Any type.

I’ll start fleshing out some basic implementation logic for each in a Perl 6 class that does the corresponding role. I’ll probably use PostgreSQL as the first driver and the guts of MiniDBD::Pg as inspiration.

The first minor milestones will be creating connections, then execute non-selects, then selects then prepared statements. Somewhere along the way I expect they’ll be a Perl 6 DBDI driver implemented for the Perl 6 MiniDBI project. The next key step would be to start refactoring the code heavily so anyone wanting to implement a new driver should only have to implement the driver specific parts. (There are some JDBC driver toolkits that can provide useful ideas for that.)

What needs doing

There’s a TODO file in the repository that lists the current items that need working on.

One fairly simple item is to add a --prefix option to specify an extra leading name for the generated role. So java.sql.Savepoint with a prefix of DBDI would generate a DBDI::java::sql::Savepoint role.

Another item, less simple but more important, is to automatically discover the values of constants and embed them into the generated file. Probably the best way to do that is to extend the parser (which uses Parse::RecDescent) to parse the verbose-mode output of javap, which includes those details.

There are plenty of others.

How you can get involved

Firstly, come and say “Hi!” in the #dbdi IRC channel on irc.freenode.net.

The code is on github. You can get commit access by asking on the #perl6 channel.

There’s also a mailing list at dbdi-dev@perl.org which you can subscribe to.

I look forward to hearing from you!



  1. When I say “Perl 6 has the potential to become a very popular language” I do so with typical British Understatement.

Filed under: perl, software Tagged: dbdi, java, perl, perl6

use Perl Journal Search: Rakudo Star Install Party (2010.07.28 14:44)

Rakudo Star Install Party (2010.07.28 14:44)

Hi Mongers,

I'd like to offer my place in Bernal Heights Tuesday next week from 7:30pm until whenever for a Raduko Star installation & Perl 6 lightning talks. As some of you know a significant milestone in Perl 6's release history is coming up this Thursday, http://rakudo.org/node/73 and what better way to get through an install than with local PM'ers!

For those that haven't been chez moi we have a basement, bar, projector, wifi, yard, BBQ, etc so we can eat, drink & give presentations. There's space for at least a dozen seated inside, and more outside (for those that can withstand the Day Star).

Who's interested in something like this? How about giving a talk?
Doesn't need powerpoint but we have a screen & sound if you do.
Anything at all raduko/perl6 related seems cool. Ping me off-list and I'll collate.

Summary:
What: Rakudo Star Install Party
When: Tuesday 3rd August 2010, 19:30 'til (e.g.) 22:00
Where: Paul's place, SF, 94110 (address on RSVP)
What to bring: computer, snacks & drinks (although I'll seed unless someone wants to sponsor it?!). We could even BBQ!

Bonus feature: there's a ton of interesting links in bite-sized chunks at http://twitter.com/rakudoperl

Paul

Announcement posted via App::PM::Announce

RSVP at Meetup - http://www.meetup.com/San-Francisco-Perl-Mongers/calendar/14243128/

use Perl Journal Search: You just upload your application, ... (2010.07.28 13:00)

You just upload your application, ... (2010.07.28 13:00)
It is amazing what happened to the Python thanks to just one company. The killer feature of that company is that they can handle and manage millions of servers and even give them for a public usage => "..., there are no servers to maintain: You just upload your application, and it's ready to serve your users.". I would like this to be true one day for Perl too!I really do. In coming months (years?) I'll try to plug together « MiniCPANInject + SmokeTesting + ContinuousIntegration + Virtualization + Debian + Monitoring » to create an architecture for Debian-Perl hosting. Actually who cares about OS used, when the uploaded code just works, right?... A hosting that is aware that one server is not enough for everyone and will offer an architecture for development, user-acceptance, staging and production environments to start with a project from $day == 1. (crossposted)

Planet Perl: Writing a perl REPL part 2 - a history plugin

So, last time we got from scratch to a basically working simple perl REPL. So now it's time to start writing plugins, since currently it's disturbingly basic and only really useful for ... well, for making a blog post about how it works at all :) ...

Read and post comments | Send to a friend

Perlsphere: Re: SDL 2.503 Released!

Hi again,<p>The `cpan pip` &amp;&amp; `pip<br><a href="http://sdlperl.ath.cx/releases/SDL-2.504.tar.gz`">http://sdlperl.ath.cx/releases/SDL-2.504.tar.gz`</a> commands both<br>succeeded but `cpan Games::FrozenBubble` can&#39;t find the installed<br>2.504 &amp;&amp; tries to install 2.503 then fails again. I don&#39;t understand<br>why it can&#39;t find the new one. Do I need to run `pip<br>Games::FrozenBubble` instead or something else to get the pip&#39;d 2.504<br>to be found as an acceptable prerequisite?<p>Thanks,<br>-Pip<br>P.S. I like that the utility is my name. =)<p>On Tue, Jul 27, 2010 at 18:30, Kartik Thakore &lt;<a href="mailto:thakore.kartik@gmail.com">thakore.kartik@gmail.com</a>&gt; wrote:<br>&gt; On 2010-07-27, at 8:51 PM, Pip Stuart &lt;<a href="mailto:pipstuart@gmail.com">pipstuart@gmail.com</a>&gt; wrote:<br>&gt;&gt; Hi Kartik,<br>&gt; Hi,<br>&gt;&gt;<br>&gt;&gt; Thanks for all the awesome SDLPerl work you&#39;ve been doing. It&#39;s much<br>&gt;&gt; appreciated. I&#39;d like to get back into some SDLPerl hacking &amp;&amp; to help<br>&gt;&gt; you test releases &amp;&amp; features.<br>&gt;&gt;<br>&gt;&gt; Earlier today, I tried to run `perl -MCPAN -e &quot;install SDL&quot;`, but it<br>&gt;&gt; failed &amp;&amp; I was hoping you could please help me get it (&amp;&amp; the<br>&gt;&gt; Games::FrozenBubble beta) installed &amp;&amp; running, when you have time.<br>&gt;&gt; Force install didn&#39;t work &amp;&amp; I&#39;m not sure what to try next, so please<br>&gt;&gt; advise. Do you know what I need to do to get around the libpng error<br>&gt;&gt; &amp;&amp; should I have a threaded Perl or smpeg too? I&#39;ve pasted the<br>&gt;&gt; conclusion of my build below to help diagnose.<br>&gt;<br>&gt; The png is a error but we have fixed it do:<br>&gt;<br>&gt; cpan pip<br>&gt; pip <a href="http://sdlperl.ath.cx/releases/SDL-2.504.tar.gz">http://sdlperl.ath.cx/releases/SDL-2.504.tar.gz</a><br>&gt;<br>&gt; This will be on CPAN later this week.<br>&gt;<br>&gt; Also a threaded Perl is not necessecary but recommended.<br>&gt;<br>&gt; Try frozen-bubble again after installing this.<br>&gt;&gt;<br>&gt;&gt; Thanks again,<br>&gt;&gt; -Pip<br>&gt;<br>&gt; No problem.<div class="blogger-post-footer"><img alt=""></div> <p><a href="http://feedads.g.doubleclick.net/~a/twcNNQcq7soTDPGW4YuwamoGn3M/0/da"><img src="http://feedads.g.doubleclick.net/~a/twcNNQcq7soTDPGW4YuwamoGn3M/0/di"></img></a><br/> <a href="http://feedads.g.doubleclick.net/~a/twcNNQcq7soTDPGW4YuwamoGn3M/1/da"><img src="http://feedads.g.doubleclick.net/~a/twcNNQcq7soTDPGW4YuwamoGn3M/1/di"></img></a></p><img src="http://feeds.feedburner.com/~r/YetAnotherPerlGameHackeryapgh/~4/GB1yRwVfZC0">

Planet Perl: Perl is ready for HTML5

A lot of amazing HTML5 applications built with Mojolicious and Perl have recently popped up.

This screencast contains a little preview for an upcoming SSH client built by vti running right in your browser, communicating through WebSockets with a Mojolicious server in the background.

You can actually try the IRC client shown in the screenshot above at http://dev.xantus.org and say hello to us, it was built by xantus to showcase ExtJS, Mojolicious and cross browser WebSockets. (Code on GitHub)

Time to get as excited about HTML5 as we are! :)

Permalink | Leave a comment  »

Perlsphere: Perl is ready for HTML5

A lot of amazing HTML5 applications built with Mojolicious and Perl have recently popped up.

This screencast contains a little preview for an upcoming SSH client built by vti running right in your browser, communicating through WebSockets with a Mojolicious server in the background.

You can actually try the IRC client shown in the screenshot above at http://dev.xantus.org and say hello to us, it was built by xantus to showcase ExtJS, Mojolicious and cross browser WebSockets. (Code on GitHub)

Time to get as excited about HTML5 as we are! :)

Permalink | Leave a comment  »

The Onion Stand: DuckDuckGo, a *fast* and *awesome* web search engine (in Perl!)

More than often we hear people in the Perl community asking for more Perl applications and solutions instead of just modules. Well, Gabriel Weinberg (YEGG, on CPAN) did just that!

His new creation is called DuckDuckGo (DDG for short), a search engine with lots of cool features, like:

  • It's blazing fast! Google's search results doesn't quite make it for me, but I could get to the "right" result in the list (even in other pages) really fast, so is was one of the biggest blockers for me in switching to other engines. No more :-)

  • Official sites are labelled and displayed on top.

  • No ads above results, and actual privacy! Unlike Google, DDG does not track users, nor displays "sponsored links" on top of your search.

  • Zero-click info is an amazing way to find what you're looking for in your search without having to follow any links. Let DDG do the hard work for you!

  • Several goodies ready for you: go to the first result prepending a "!" to your search, find your IP address by simply querying "ip", get random numbers, test a regexp, and much, much more!

  • site:, filetype:, inurl:, AND, OR, and all your favorite advanced operators work too!

  • Keyboard shortcuts and customizations let you setup fonts, colors and much more! If you don't like to use the mouse, you can do everything via the keyboard.

  • Encrypted search, just use https:// instead of http://
Read the About and FAQ for more features and information, and give it a try. You might be surprised :-)

Want to help promote more Perl-based solutions? Sick and tired of Google search? Switch now!


Oh, did I mention it is **fast** ??

Cheers!

use Perl Journal Search: Desperate Perl; or A Tale of Two Languages (2010.07.27 13:25)

Desperate Perl; or A Tale of Two Languages (2010.07.27 13:25)
Piers Cawley's A tale of two languages (if you haven't already seen it) speaks to the public perception that Perl remains a desperation language ("Desperate Perl") suited only for gluing things together when nothing else will do.Meanwhile elsewhere in the real world, there is plenty (possibly a majority IMHO) of maintainable, understandable, well-written, efficient Perl code ("Large Scale Perl" as described by Piers). Worth a read. (Although I like the name "Desperate Perl" a lot, I think that the names "Scripting Perl" and "Programming Perl" also describe these separate Perl programming styles in a less-emotional fashion (which is occasionally useful.))

Planet Perl: Perlbuzz news roundup for 2010-07-27


These links are collected from the Perlbuzz Twitter feed. If you have suggestions for news bits, please mail me at andy@perlbuzz.com.

Perlbuzz: Perlbuzz news roundup for 2010-07-27


These links are collected from the Perlbuzz Twitter feed. If you have suggestions for news bits, please mail me at andy@perlbuzz.com.

Perlsphere: perlprogramming.org looking for a nice home

I picked up this domain name a while ago since it was available and people were saying how Perl needs better visibility. (I was probably inspired by Tim's post about TIOBE). Currently, I just redirect to perl.org. The domain is coming up for renewal and I'll gladly sign it over to someone who can make a good case for what they plan to do with it to benefit the perl community.

Planet Perl: perlprogramming.org looking for a nice home

I picked up this domain name a while ago since it was available and people were saying how Perl needs better visibility. (I was probably inspired by Tim's post about TIOBE). Currently, I just redirect to perl.org. The domain is coming up for renewal and I'll gladly sign it over to someone who can make a good case for what they plan to do with it to benefit the perl community.

Perlsphere: Bryar security hole

Someone on IRC reported a bug in Bryar. Namely that a Naughty Person can exploit the feature that notifies you of blog-spam by email to execute arbitrary code on your machine, as the user you run Bryar under.<p>A patched release is on the way to the CPAN, and you are strongly urged to upgrade.

Perlsphere: Perl isn't dieing

Perl isn't dieing, but it tells me that it wishes it was. Last night it went out on the piss with Python and Ruby (PHP was the designated driver) and it did rather too many cocktails. It isn't quite sure what happened, but it woke up in the gutter in a puddle of its own fluids and its head hurts a <em>lot</em>.<p>It asked me to ask you all to keep the volume down.

Perlsphere: Thanks, Yahoo!

[originally posted on Apr 3 2008]<p>I'd like to express my warm thanks to the lovely people at Yahoo and in particular to their bot-herders. Until quite recently, their web-crawling bots had most irritatingly obeyed robot exclusion rules in the robots.txt file that I have on <a href="http://cpandeps.cantrell.org.uk/">CPANdeps</a>. But in the last couple of weeks they've got rid of that niggling little exclusion so now they're indexing all of the CPAN's dependencies through my site! And for the benefit of their important customers, they're doing it nice and quickly - a request every few seconds instead of the pedestrian once every few minutes that gentler bots use.<p>Unfortunately, because generating a dependency tree takes more time than they were allowing between requests, they were filling up my process table, and all my memory, and eating all the CPU, and the only way to get back into the machine was by power-cycling it. So it is with the deepest of regrets that I have had to exclude them.<p><a href="http://www.yahoo.com/">Cunts</a>.<p>[update] For fuck's sake, they're doing it again from a different netblock!

Perlsphere: This Week's Contribution to Perl 6 Week 6: Improve Book markup

This Week's Contribution to Perl 6 can be found on masak's blog.

Perlsphere: Module pre-requisites analyser

As a service to module authors, here is a tool to show a module's pre-requisites and the test results from the CPAN testers. So before you rely on something working as a pre-requisite for your code, have a look to see how reliable it and its dependencies are.

Perlsphere: This Week's Contribution to Perl 6 Week 5: Implement Str.trans

For this week's contribution to Perl 6 we ask you to write some Perl 6 code that implements the trans method for Rakudo Perl. This is the backend for the tr/// operator.

(Introduction to this series of challenges)

Background

The Perl 6 transliteration operator is also available as a method. It replaces all occurrences of some characters (or regexes) with a substitution string. The easiest case is:

say 'Hello World'.trans('a' => 'A', 'e' => 'E', 'O' => 'O');
# output: HEllO WOrld

say 'Hello World'.trans('aeo' => 'AEO');
# same thing

The previous iteration of Rakudo had a PIR-based (and complicated) implementation for trans. There are tests in the official test suite for .trans.

What you can do

Please write a method trans that implements part of the specification. Since it's quite a lot to do, it's OK to only do parts. For example I recommend to omit regexes altogether for now, and only implement literal string patterns. The easiest approach is probably to create a hash that maps each input pattern character to the transliteration, and walk the string character by character by iterating over self.comb.

To test it without actually having to recompile Rakudo after each change, I recommend to copy the test that Rakudo can parse (ie the method tests, not the tests for tr///), and start it with

use v6;

use Test;

use MONKEY_TYPING;
augment class Str {
    method trans(*@patterns)  {
        # do your hacking here
        'wrong return value';
    }
}

plan *;

is("ABC".trans( ('A'=>'a'), ('B'=>'b'), ('C'=>'c') ),
    "abc",
    "Each side can be individual characters");

is("XYZ".trans( ('XYZ' => 'xyz') ),
    "xyz",
    "The two sides of the any pair can be strings interpreted as tr/// would multichar");

...

done_testing;

Submission

Please send your submission to the perl6-compiler@perl.org mailing list, and set me (moritz@faui2k3.org) as CC, because the mailing list sometimes has a large delay.

If you have any questions, please ask the mailing list, me or (preferred) on our IRC channel, #perl6.

The best/most extensible/most complete/prettiest/whatever submission will make it into the next release of Rakudo.

Update: There have been two submissions discussed on perl6-compiler, and another one submitted as gist. If you want to work on this challenge, please improve one of the existing submissions, not write a new one from scratch.

Perlsphere: This Week's Contribution to Perl 6 Week 8: Implement $*ARGFILES for Rakudo

For this week's contribution to Perl 6 we ask you to implement the $*ARGFILES special variable (and underlying object) for Rakudo.

(Introduction to this series of challenges)

Background

In Perl 5, there is a "magic" way to iterate over input: while (my $line = <>) { ... }. This reads from standard input if no command line arguments were provided. If there are command line arguments, they are taken as file names, and <> iterates over the contents of these files.

In Perl 6 this magic is performed with the $*ARGFILES special variable. Please implement it!

To do that, you have to understand how file reading works in Perl 6. Once you have a file handle, there are two ways to read lines: either by calling $handle.get, which returns just one line, or by calling $handle.lines, which returns a (lazy) list of all the remaining lines.

You can obtain the command line arguments from @*ARGS, open a file with my $handle = open $filename; for reading; And finally you can use lines('filename') to read all lines from a file.

What you can do

Implement a backend class for $*ARGFILES. You can do that in normal Perl 6 code, no need to change the actual compiler. Once that's done, we will plug it into Rakudo. Your code might look like this:

class IO::ArgFiles {
    has @!filenames;
    method get() { ... }
    method lines() { ... }
    method filename() {
        # return the current filename, or '-' if standard input
        ...
    }
}
my $*ARGFILES = IO::ArgFiles.new(filenames => @*ARGS);
.say for $*ARGFILES.lines();

(Of course this is only a rough skeleton, you might need to change some details, or add some things).

Submission

Please submit your source code to the perl6-compiler@perl.org mailing list (and put moritz@faui2k3.org on CC, because the mailing list sometimes lack quite a bit).

Update:: there have been two submissions, and a mixture of both has been applied.

Perlsphere: Common Perl 6 data processing idioms

NAME

"Perl 5 to 6" Lesson 27 - Common Perl 6 data processing idioms

SYNOPSIS

  # create a hash from a list of keys and values:
  # solution 1: slices
  my %hash; %hash{@keys} = @values;
  # solution 2: meta operators
  my %hash = @keys Z=> @values;

  # create a hash from an array, with
  # true value for each array item:
  my %exists = @keys Z=> 1 xx *;

  # limit a value to a given range, here 0..10.
  my $x = -2;
  say 0 max $x min 10;

  # for debugging: dump the contents of a variable,
  # including its name, to STDERR
  note :$x.perl;

  # sort case-insensitively
  say @list.sort: *.lc;

  # mandatory attributes
  class Something {
      has $.required = die "Attribute 'required' is mandatory";
  }
  Something.new(required => 2); # no error
  Something.new()               # BOOM

DESCRIPTION

Learning the specification of a language is not enough to be productive with it. Rather you need to know how to solve specific problems. Common usage patterns, called idioms, helps you not having to re-invent the wheel every time you're faced with a problem.

So here a some common Perl 6 idioms, dealing with data structures.

Hashes

  # create a hash from a list of keys and values:
  # solution 1: slices
  my %hash; %hash{@keys} = @values;
  # solution 2: meta operators
  my %hash = @keys Z=> @values;

The first solution is the same you'd use in Perl 5: assignment to a slice. The second solution uses the zip operator Z, which joins to list like a zip fastener: 1, 2, 3 Z 10, 20, 30 is 1, 10, 2, 20, 3, 30. The Z=> is a meta operator, which combines zip with => (the Pair construction operator). So 1, 2, 3 Z=> 10, 20, 30 evaluates to 1 => 10, 2 => 20, 3 => 30. Assignment to a hash variable turns that into a Hash.

For existence checks, the values in a hash often doesn't matter, as long as they all evaluate to True in boolean context. In that case, a nice way to initialize the hash from a given array or list of keys is

  my %exists = @keys Z=> 1 xx *;

which uses a lazy, infinite list of 1s on the right-hand side, and relies on the fact that Z ends when the shorter list is exhausted.

Numbers

Sometimes you want to get a number from somewhere, but clip it into a predefined range (for example so that it can act as an array index).

In Perl 5 you often end up with things like $a = $b > $upper ? $upper : $b, and another conditional for the lower limit. With the max and min infix operators, that simplifies considerably to

  my $in-range = $lower max $x min $upper;

because $lower max $x returns the larger of the two numbers, and thus clipping to the lower end of the range.

Since min and max are infix operators, you can also clip infix:

 $x max= 0;
 $x min= 10;

Debugging

Perl 5 has Data::Dumper, Perl 6 objects have the .perl method. Both generate code that reproduces the original data structure as faithfully as possible.

:$var generates a Pair ("colonpair"), using the variable name as key (but with sigil stripped). So it's the same as var => $var. note() writes to the standard error stream, appending a newline. So note :$var.perl is quick way of obtaining the value of a variable for debugging; purposes, along with its name.

Sorting

Like in Perl 5, the sort built-in can take a function that compares two values, and then sorts according to that comparison. Unlike Perl 5, it's a bit smarter, and automatically does a transformation for you if the function takes only one argument.

In general, if you want to compare by a transformed value, in Perl 5 you can do:

    # WARNING: Perl 5 code ahead
    my @sorted = sort { transform($a) cmp transform($b) } @values;

    # or the so-called Schwartzian Transform:
    my @sorted = map { $_->[1] }
                 sort { $a->[0] cmp $b->[0] }
                 map { [transform($_), $_] }
                 @values

The former solution requires repetitive typing of the transformation, and executes it for each comparison. The second solution avoids that by storing the transformed value along with the original value, but it's quite a bit of code to write.

Perl 6 automates the second solution (and a bit more efficient than the naiive Schwartzian transform, by avoiding an array for each value) when the transformation function has arity one, ie accepts one argument only:

    my @sorted = sort &transform, @values;

Mandatory Attributes

The typical way to enforce the presence of an attribute is to check its presence in the constructor - or in all constructors, if there are many.

That works in Perl 6 too, but it's easier and safer to require the presence at the level of each attribute:

    has $.attr = die "'attr' is mandatory";

This exploits the default value mechanism. When a value is supplied, the code for generating the default value is never executed, and the die never triggers. If any constructor fails to set it, an exception is thrown.

MOTIVATION

N/A

Perlsphere: This Week's Contribution to Perl 6 Week 3: Write supporting code for the MAIN sub

For this week's contribution to Perl 6 we ask you to write some Perl 6 code that parses command line arguments, and might end up in the code base of a Perl 6 compilers.

(Introduction to this series of challenges)

Background

In Perl 6 you can write a sub MAIN that is automatically called when the script is run, and it handles command line parsing for you.

So for example if you write

sub MAIN($filename, *@rest, :$verbose) {
    ...
}

And you call the script as

perl6 create_many_copies.pl --verbose=2  /etc/password pw1 pw2 pw3

The parameters are automatically set to $filename = '/etc/password', @rest = ('pw1', 'pw2', 'pw3') and $verbose = 2.

What you can do

Write a subroutine in Perl 6 that takes an array of command line arguments, and a hash of option names that are declared as Bool, and returns an array of positional arguments, and a hash of named arguments

sub process-cmd-args(@args, %boolean-names) {
    ...
    return @positional-arguments, %named-arguments;
}

It should separate the named arguments (options) and the ordinary, positional arguments. For example a command line argument of --myname=23 should be result in a hash entry %named-arguments{'myname'} = 23. If a named option is declared as type Bool, then --myoption foo is turned into %named-arguments{'myoption'} = True, @positional-arguments = 'foo'. Otherwise it is taken as %named-arguments{'myoption'} = 'foo'.

The specification describes the various syntax forms in detail, but you are very welcome to implement only parts of them. For example it's recommended to ignore the negation forms, short names and spaces inside options.

We will then use the separate positional and named arguments to call the MAIN routine.

If you need some more background on how to write Perl 6 code, I recommend to start with a book that is currently being written (you can find a fairly up-to-date PDF version here.). See also our documentation overview.

Submission

Your program should run with the current Rakudo Perl 6 compiler - bonus points if you also provide some tests.

Please send your submission to the perl6-compiler@perl.org mailing list, and set me (moritz@faui2k3.org) as CC, because the mailing list sometimes has a large delay.

Update:: patrickas has submitted one implementation to this github repository. Instead of starting your own implementation, you can also contribute to this one (ask on #perl6 for commit access), and of course you're still eligible for winning a cool Perl 6 or Rakudo t-shirt.

If you have any questions, please ask the mailing list, me or (preferred) on our IRC channel, #perl6.

I will try to integrate the best submission into Rakudo (though it might not happen before the upcoming release on Tuesday).

Perlsphere: cgit syntax highlighting

For the last few months I've been using <a href="http://git-scm.com/">git</a> for my version control system. It's better than CVS because it can handle offline commits. So if I'm using my laptop on a train, I can still use version control without having to have a notwork connection.<p>And to give a pretty web front-end to it for other people to <a href="http://www.cantrell.org.uk/cgit/">read code</a> without having to check it out of the repository, I use <a href="http://hjemli.net/git/cgit/">cgit</a>, which I mostly chose because it's a dead simple CGI and not a huge fancy application.<p>One problem with cgit is that by default it doesn't do code highlighting. But it has the ability to run blobs of code through any filter you care to name before displaying them, so to get something nice like <a href="http://www.cantrell.org.uk/cgit/cgit.cgi/perlmodules/tree/Sub-WrapPackages/lib/Sub/WrapPackages.pm?id=db12893c451365b8f546b9f253735be1c542b6c0">this</a> all you need to do is write a highlighter and add a single line to your cgitrc:<p><code>source-filter=/web/www.cantrell.org.uk/cgit/highlighter</code><p>My highlighter program is this:<p><pre> 1 #!/usr/local/bin/perl 2 3 <b><font color="#8B008B">use</font></b> warnings; 4 <b><font color="#8B008B">use</font></b> strict; 5 6 <b><font color="#8B008B">my</font></b> <font color="#00688B">$file</font> = <b><font color="#8B008B">shift</font></b>; 7 8 <b><font color="#8B008B">if</font></b>(<font color="#00688B">$file</font> =~ <font color="#CD5555">/\.(p[ml]|t)$/i</font>) { 9 <b><font color="#8B008B">system</font></b> <font color="#CD5555">&quot;/usr/local/bin/perltidy -html -st -ntoc -npod -pre -nss -nnn&quot;</font> 10 } <b><font color="#8B008B">else</font></b> { 11 <b><font color="#8B008B">system</font></b> <font color="#CD5555">&quot;cat -n&quot;</font>; 12 } </pre><p>

Perlsphere: Gabor: Keep going

After reading this blog post, I just want to say: keep going.

Gabor does really awesome things for Perl (and especially for Perl 6, which I tend to notice more): beginner's tutorials, screencasts, training courses, writes an IDE and so on. If his primary interest was his own success, his priorities would be quite different.

I hope that Gabor doesn't pay too much attention to the hostilities from parts of the Perl community, and I wish him and us all the best for his current project.

Perlsphere: This Week's Contribution to Perl 6 Week 4: Implement :samecase for .subst

For this week's contribution to Perl 6 we ask you to implement an option in the string substitution backend that is be used for s/// style replacements.

(Introduction to this series of challenges)

Background

In Perl 6, the string substitution operation s/// has a method backend. Instead of s:g/foo/bar/ (globally substitute foo by bar) you can write:

say 'some foo with sugar'.subst(/foo/, 'bar', :g);

Currently Rakudo doesn't parse the adverbs at the front, but supports the named arguments in the method form.

What you can do

Implement the :samecase named parameter. With this option, the case (upper/lower) of the original string is applied to the substitution:

say 'The foo and the bar'.subst(/:i the/, 'that', :g, :samecase);
# should produces 'That foo and that bar'

The actual case transformation is implemented in form of the samecase($substitution, $pattern) function already. If the replacement part is actually a code object, the samecase translation should apply to its return value.

Your task is to hook that function into the subst method in src/core/Cool-str.pm, and put some tests into t/spec/S05-substitutions/subst.t in the pugs repository that demonstrate that your code works.

When you've modified the test and/or the source file, you can run it with

make t/spec/S05-substitution/subst.t

Submission

Please submit your patches to the perl6-compiler mailing list, and CC' me (moritz@faui2k3.org). As always, feel free to ask any questions about this question either on that mailing list, or on our IRC channel.

Update: A working patch from Hongwen Qiu has been applied, as well as some tests; more tests are still welcome.

Perlsphere: Ill

I am ill. I've been ill since Thursday, with a cold. You're meant to be able to cure a cold with [insert old wives tale remedy here] in 5 days, or if you don't, it'll clear itself up in just under a week. So hopefully today is the last day.<p>So what have I done while ill?<p>On Friday I became old (see previous post), and went to the <a href="http://www.royalacademy.org.uk/exhibitions/byzantium/">Byzantium</a> exhibition at the Royal Academy. It was good. You should go.<p>Saturday was the <a href="http://conferences.yapceurope.org/lpw2008/">London Perl Workshop</a>. My talk on closures went down well, and people seemed to understand what I was talking about. Hurrah! I decided that rather than hang around nattering and going to a few talks, I'd rather hide under my duvet for the rest of the day.<p>I mostly hid on Sunday too, and spent most of the day asleep. In a brief moment of productivity, I got my laptop and my phone to talk to each other using magic interwebnet bluetooth stuff. I'd tried previously without success, but that was with the previous release of OS X. With version X.5 it seems to Just Work, so no Evil Hacks were necessary.<p>The cold means that I can't taste a damned thing, not even bacon. So now I know what it's like to be Jewish. Being Jewish <em>sucks</em>.<p>And today, I am still coughing up occasional lumps of lung and making odd bubbling noises in my chest, although my nasal demons seem to be Snotting less than they were, so hopefully I'll be back to normal tomorrow.

Perlsphere: Devel::CheckLib can now check libraries' contents

Devel::CheckLib has grown a new feature. As well as checking that libraries and headers exist, it can now also check that particular functions exist in a library and check their return values. This will be particularly useful if you need to check that a particular version of a library is available.

It works if you have a Unixish toolchain. I need to wait for the CPAN-testers reports to see if I managed not to break anything on Windows. Unfortunately, even though the lovely Mr. Alias has worked hard to make Windows machines available to developers, I found it to be just too hard to use. Even downloading my code to the Windows machine was hard, as Windows seemed to think it knew better and shouldn't download the file I told it to download. Then once I had downloaded it, Windows decided to hide it somewhere that I couldn't get to using the command line. So I gave up.

I might try again once there are some decent tools on the machines: wget, tar, and gzip at minimum, as given those I can quickly bootstrap anything else. Software development isn't just about having compilers available.

Perlsphere: Want to write shiny SVG graphics with Perl 6? Port Scruffy!

First let my apologize for waiting so long to come up with a new "weekly" Perl 6 challenge - I'm running out of ideas, and the one I have left needs more time to prepare.

Instead I want to motivate you to help porting the ruby scruffy charting library to Perl 6. It can generate shiny SVG graphics (they are currently broken on their main website, hence the waybackmachine link).

There's already an initial version Perl 6 port called "tufte", but it's not running yet. It needs your help. If you know a little ruby, and want to learn some more Perl 6, join #perl6, ask for a commit bit, and translate some ruby code into Perl 6. And in the end you'll be rewarded with nice SVG charts :-).

Perlsphere: This Week's Contribution to Perl 6 Week 7: Implement try.rakudo.org

For this week's contribution to Perl 6 we ask you to write a web shell for Rakudo, just like tryruby.org (or this js course) but for Perl 6 + Rakudo.

(Introduction to this series of challenges)

Background

We want a website like tryruby, but for Perl 6: A combination of web shell and built-in tutorial.

The idea is that for each session a supervisor/controller process runs on the server, which talks to a Rakudo process, and listens at a local socket. A CGI script receives the program lines to be executed, looks up the port number in a session file or database, and connects via a local socket to the controller process.

planned architecture of try.rakudo.org

What you can do

You can help to make try.rakudo.org come real. This week I ask you to work on the front end, ie. a HTML page with some javascript that works like a shell; it sends the command entered by the user to a CGI script, and displays its response.

It should also be able to show instructions, and advance to the next instruction when the user has entered what he should.

Submission

A stub of the source code can be found on github. Please join our IRC channel and ask for commit access to that repository.

Then fill in any parts you want, primarily concerning the front-end. If you have any questions, don't hesitate to ask either on the IRC channel, or on the perl6-compiler@perl.org mailing list (and put moritz@faui2k3.org on CC, because the mailing list sometimes lack quite a bit).

Update: We now have a frontend and parts of the backend, by courtesy of cygx++. If you want to join the project, please improve what we have now instead of submitting a new solution.

Perlsphere: POD includes

One of my CPAN distributions is <a href="http://search.cpan.org/search?query=CPAN-FindDependencies">CPAN-FindDependencies</a>. It contains a module CPAN::FindDependencies, and a simple script that wraps around it so you can view dependencies easily from the command line. That script, naturally, has a man page. However, that manpage basically says "if you want to know what arguments this program takes, see the CPAN::FindDependencies docs". This is Bad from a usability point of view, good from a not-duplicating-stuff point of view, and good from a laziness point of view. Which means that it's Bad.<p>So, the solution.<p><blockquote><tt> =over<p>#include shared/parameters<p>=back </tt></blockquote><p>and some <a href="http://www.cantrell.org.uk/cgit/cgit.cgi/perlmodules/tree/CPAN-FindDependencies/Makefile.PL?id=b643a4d95f300552b9af9e7edd1fef9ae96543b3">Magic</a> that does the <a href="http://gcc.gnu.org/onlinedocs/gcc-4.3.3/cpp/">cpp-stylee</a> substitution at <code>make dist</code> time. Note the 'dist' section in my call to <code>WriteMakefile</code>.<p>This is, of course, crying out to be made less horribly hacky, but it works for now, so I'm happy.<p>My original idea was to write some crazy shit that would do the #include at install-time, when the user was installing my code. But that has the disadvantage that tools like <a href="http://search.cpan.org/">search.cpan</a> wouldn't show it properly, as they simply look at the files in the distribution. So this does the #includes at the last moment just before I package up the code and upload to the PAUSE. You lovely people get the right documentation in all the right places, I only have to maintain it in one place so it stays in sync, and (in the interests of Laziness) I don't have to remember to run any extra scripts before releasing, <code>make dist</code> just Does The Right Thing.

Perlsphere: My personal "I want a PONIE" wish list for Rakudo Star

In June we'll see a special Rakudo release codenamed Rakudo Star. I've done some development with and of Rakudo, and here's the list of features and bug fixes that I think are essential for a successful and well-received release:

  • Backtraces with Perl 6 file names and line numbers (Update 2010-05-30: jnthn implemented those)
  • Proper closure cloning (Update 2010-06-07: pmichaud has fixed it)
  • Match objects which return Perl 6 (and not parrot) data structures (Update 2010-05-30: pmichaud laid the foundations for that, and I got it to a "good enough" state).
  • /<foo>/ should pick up a regex named foo from the lexical scope, not only from method lookup. (Update 2010-07-21: This is not going to happen, since the spec will change significantly at this point).
  • Using the same list or iterator twice returned from map or gather/take should work (Update: pmichaud fixed that in The Big List Refactor, which was merged shortly before the 2010.06 release).

Other things that I consider nice to have, but not essential:

  • $/ should be available in the RHS of s/// (seems hard to do with current Parrot semantics)
  • use currently only accepts pairs, not proper argument lists. Would be nice to have that.
  • General Whatever-currying (ie * op 3 returns a closure of type WhateverCode) (Update: jnthn implemented it one or two days after this blog post)
  • Currently user-defined operators hide candidates of the same name from outer scopes. This is rather annoying.

Perlsphere: YAPC::Europe 2007 report: day 1

As is becoming normal, I used the times between talks to bugfix some of my modules - this time <a href="http://search.cpan.org/~dcantrell/Tie-STDOUT-1.03/">Tie::STDOUT</a> and <a href="http://search.cpan.org/~dcantrell/Data-Transactional-1.0/">Data::Transactional</a>. The former was failing on perl 5.6, the latter on 5.9.5. The former was a bug in perl (you can't localise tied filehandles and expect the tieing to go away in 5.6, so it now declares a dependency on 5.8), the latter was a bug in my code.<p>Philippe Bruhat's talk on <a href="http://search.cpan.org/~book/Net-Proxy-0.08/">Net::Proxy</a> was great - you can tell it's great because I came away with ideas for at least four things that I <em>need</em> to write. First up will be a plugin for it to allow the user to specify minimum and maximum permitted data rates for proxied connections. This will permit bandwidth limits for maximum permitted rates, but will also help to defeat IDSes doing traffic analysis if you specify a minimum permitted data rate.<p>This will protect (eg) ssh sessions from being identified based on their very bursty traffic pattern, by "filling in the blanks" with junk data.<p>In the evening, the CPAN-testers BOF was productive.

Perlsphere: Palm Treo call db module

To make up for a disappointing gap in Palm's software for the Treo smartphone, I wrote a <a href=http://www.cantrell.org.uk/david/tech/treo/call-dumper/>small perl script</a> to parse the database that stores my call history. I then re-wrote it as <a href=http://search.cpan.org/search?query=Palm%3A%3ATreoPhoneCallDB>a re-useable module</a> which also figgers out whether the call was incoming or outgoing.

Perlsphere: This Week's Contribution to Perl 6 Week 9: Implement Hash.pick for Rakudo

For this week's contribution to Perl 6 we ask you to implement the Hash.pick method (which does a weighted random selection) for Rakudo.

(Introduction to this series of challenges)

Background

In Perl 6 the List class has a method called pick, which randomly selects one item from a list. It has a few more options too:

<a b c>.pick;       # pick one random element
<a b c>.pick(2);    # pick two distinct, random elements
<a b c>.pick(2, :replace); # pick two random elements, it's ok
                           # if they are the same
<a b c>.pick(*);    # return a random permutation of the elements
<a b c>.pick(*, :replace); # infinite, random stream of elements

This is already implemented through several multi methods in Rakudo.

Now the specification describes such a method for hashes too (actually it talks about Bags, but Rakudo doesn't have Bags yet. Pretend it says "Hash" instead). It assumes that each value in the hash is numeric, and that the value is a weight that determines the probability of picking one value. For example

{a => 1, b => 2}.pick;  # returns 'a' with probability 1/3
                        # and 'b' with probability 2/3

{a => 1, b => 2}.pick(*);  # <a b b> with probability 1/3
                           # <b a b> with probability 1/3
                           # <b b a> with probability 1/3
{a => 1, b => 0.5}.pick(*) # dies, because the weights aren't all integers
{a => 1, b => 0.5}.pick(*, :replace)  # ok 

What you can do

Implement Hash.pick. It's ok if your patch doesn't cover all cases. It would be nice if it supported non-integer weights.

Hint: this could be done by storing a list of accumulated weights, and a list of keys.

{a => 1, b => 2.5, c => 1}

# could translate to 
my @keys = ('a', 'b', 'c');
my @accumulated_weights = (1, 3.5, 4.5);

# now pick a random number between 0 and 4.5,
# find the next-highest index in @accumulated_weights
# with a binary search, and then use that to obtain the key.

Of course other schemes are fine too.

Second hint: because it takes quite some time to recompile Rakudo, it is probably easier to implement the actual logic in a function in a normal source file first, and only later move it into src/core/Hash.pm.

Submission

Please submit your source code to the perl6-compiler@perl.org mailing list (and put moritz@faui2k3.org on CC, because the mailing list sometimes lack quite a bit).

Update: there's one submission on the perl6-compiler mailing list already, which looks pretty good.

Perlsphere: This Week's Contribution to Perl 6 - Lottery Intermission

In the original "Contribute now" announcement I've promised that there would be some t-shirts to win.

Since then there have seven challenges (mostly weekly), and I've decided on the rules of the lottery:

  • Every contributor can win at most one t-shirt, even if he had submissions for multiple weeks
  • The lottery will be done on a per-week base

Of course the lottery was conducted by a Perl 6 script. Here it is:

 
use v6;

my @contribs =
    [ "patrickas", "shawjef3@<omitted>", "Dagur Valberg Johannsson", "Juan José 'Peco' San Martín"],
    [ "bubaflub" ],
    [ "patrickas", "David Green" ],
    [ "Hongwn Qiu"],
    [ "David Green", "Chris Fields", "rgrau"],
    [ "sahadev" , "Dean Serenevy"],
    [ "cygx" ],
    ;

my %winners;

for @contribs.pairs.pick(*) -> $p {
    my $week = $p.key + 1;
    my @people = $p.value.flat.grep({ !%winners{$_} });
    say "Candidates for Week $week: @people.join(', ')";;
    my $winner = @people.pick;
    say "And the winner is... $winner!";
    %winners{$winner} = $week;
}

say %winners.perl;

And then, in the moment of truth, it produced this output:

Candidates for Week 7: cygx
And the winner is... cygx!
Candidates for Week 2: bubaflub
And the winner is... bubaflub!
Candidates for Week 5: David Green, Chris Fields, rgrau
And the winner is... David Green!
Candidates for Week 1: patrickas, shawjef3@<omitted>, Dagur Valberg Johannsson, Juan José 'Peco' San Martín
And the winner is... shawjef3@<omitted>!
Candidates for Week 4: Hongwn Qiu
And the winner is... Hongwn Qiu!
Candidates for Week 3: patrickas
And the winner is... patrickas!
Candidates for Week 6: sahadev, Dean Serenevy
And the winner is... sahadev!
{"Hongwn Qiu" => 4, "patrickas" => 3, "bubaflub" => 2, "David Green" => 5,
"cygx" => 7, "sahadev" => 6, "shawjef3\@<omitted>" => 1}

If you are one of the winners, and haven't told me your address yet, please do so. Also tell me your t-shirt size, and whether you want a Rakudo or a Perl 6 t-shirt.

I'd like to thank again everybody who contributed, and The Perl Foundation for sponsoring some of the t-shirts!

Perlsphere: Number::Phone release

There's a new release, <a href=http://www.cantrell.org.uk/david/tech/perl-modules/Number-Phone-1.58.tar.gz>version 1.58</a>, of Number::Phone, my set of perl modules for picking information out of phone numbers. Changes from the previous release are that Mayotte, Reunion and Comoros can't decide which country is which, and there's the usual updates to the database of UK numbers, mostly to support the <a href=http://www.ofcom.org.uk/media/news/2007/02/nr_20070213b>new 03 numbers</a>.

Perlsphere: Wikipedia handheld proxy

I got irritated at how hard it was to use <a href="http://en.wikipedia.org/">Wikipedia</a> on my Treo. There's so much rubbish splattered around their pages that it Just Doesn't Work on such a small screen. Given that no alternatives seemed to be available - at least, Google couldn't find any - I decided to write my own <a href="http://wikiproxy.cantrell.org.uk/">Wikipedia handheld proxy</a>.<p>It strips away all the useless rubbish that normally surrounds Wikipedia pages, as well as things like the editing functions which are also hard to use on portable devices. Internally, it's implemented using <a href="http://www.perl.org/">perl</a>, <a href="http://search.cpan.org/~gaas/libwww-perl-5.806/">LWP</a>, and <a href="http://search.cpan.org/~pgollucci/mod_perl-2.0.3/">mod_perl</a>, and is hosted by <a href="http://www.keyweb.de/vrsrds/index.shtml">Keyweb.de</a>.

Perlsphere: CPANdeps upgrade

While you won't notice any changes, there have been biiiig upgrades at <a href="http://deps.cpantesters.org">CPANdeps</a>. <a href="http://www.cantrell.org.uk/cgit/cgit.cgi/cpandeps/diff/?id=2fa3ffb8d3b0597afb7a35f473086c82b8a07335&amp;id2=8df033031c2fcd9243152d35e5d8336d60264ecc">Here's the diff</a>.<p>Until now, it's used a SQLite database of test results that I downloaded every day and then mangled a bit to do things like add some necessary indices, figure out which reports are from dev versions of perl, and so on. That worked really well back in the summer of 2007, when there were only half a million reports in the database. I started worrying a bit at the beginning of 2009 when we hit 3 million, but the update happened overnight so I didn't care. But now that we've got over 6 million reports, the update would take anywhere between 8 and 14 hours. Not only is that not sustainable given the current growth rate, it also hurts the other users on that machine, because almost all of that time is spent waiting for disk I/O - which means that they're also waiting for the disk. On top of that, when you have big databases, a SQLite CGI ain't a great idea because indices have to be fetched from disk every time, so reads pound the disk too. Doubleplusungood!<p>Fun fact: SQLite is great for prototyping, but it doesn't scale :-)<p>So now it uses MySQL. Having a database daemon running all the time means that there's now some caching, so reads are quicker. In addition, given that I can't just simply fiddle with the structure of the database that I download to produce what I want, and instead have to import the data into MySQL, it now only imports new records, so the daily update takes only a few seconds.<p>I also re-jigged the structure of how it caches test results. Instead of being all in one directory with hundreds of thousands of files, they're split into a hierarchy. This probably won't have any significant effect on normal operations, but it will certainly make it faster for me to navigate around and see what's going on when people submit bug reports!

Perlsphere: Physical modeling with Math::Model and Perl 6

Let's talk about physics. I'm a physicist by education and profession, so it might be not be too surprising. But I also want to talk about programming, so please bear with me.

When physicists try to understand a system, typically they first come up with a lot of equations, and then try to solve them. Unfortunately some of those equations are quite hard to solve. I've written a module that solves them numerically, and allows you to express the equations in very simple Perl 6 code.

Getting started

Let's start with a very simple model. As a prerequisite you need the Rakudo Perl 6 compiler (latest release or current development version), and then use proto to proto install Math-Model (which also installs its dependencies).

A first model: throwing a stone horizontally into the air

Let's start with an example (to be found in examples/vertical-throw.pl in the Math-Model repository, with small modifications to unconfuse the syntax hilighter used for this page).

It describes the path of stone thrown vertically into the air.

use v6;
use Math::Model;

my $m = Math::Model.new(
    derivatives => {
        y_velocity      => 'y',
        y_acceleration  => 'y_velocity',
    },
    variables   => {
        y_acceleration  => { $:force / $:mass },
        mass            => { 1 },           # kg
        force           => { -9.81 },       # N = kg m / s**2
    },
    initials    => {
        y               => 0,               # m
        y_velocity      => 20,              # m/s
    },
    captures    => ('y', 'y_velocity'),
);

$m.integrate(:from(0), :to(4.2), :min-resolution(0.2));
$m.render-svg('throw-vertically.svg', :title('vertical throwing'));

First we declare that we use Perl 6 (use v6;), and then we load the module that does all the hard work, Math::Model.

Then comes the interesting part: the actual model. It starts by declaring that the derivative of y (which is the name we use for the current height of the stone) is called y_velocity. Likewise the derivative of y_velocity is called y_acceleration.

A derivative describes the rate of change of some other variables. Here is a short list of useful physical quantities and their derivatives:

QuantityDerivative
positionvelocity
velocityacceleration
accelerationjerk
momentumforce
energypower
chargecurrent

Next in the model are formulas for some variables. We don't need to give formulas for those values on the right-hand side of the derivatives declarations (y and y_velocity), which we will call integration variables. We just need formulas for the derivatives that are not also integration variables, and for other variables we use in the formulas.

You might remember from physics class that F = m * a, force is mass times acceleration. We use this formula for calculating the acceleration

        y_acceleration  => { $:force / $:mass },

The other variables are actually constants (but Math::Model doesn't distinguish those); mass is set to 1 kg, and the force to the -9.81 N that a mass of 1 kg experiences at the latitude where I live (Germany).

The programmer in you might ask what the heck the : in $:force means. It's a variable that is automatically a named parameter to the current block. Math::Model uses Signature introspection to find out which variables such a block depends on, and topologically sorts all variables into an order of execution that satisfies all the dependencies.

Back to the physical model; all integration variables need an initial value, which are provided on the next few lines. The line

    captures    => ('y', 'y_velocity'),

tells Math::Model which variables to record while the simulation is running.

$m.integrate(:from(0), :to(4.2), :min-resolution(0.2));
$m.render-svg('throw-vertically.svg', :title('vertical throwing'));

Finally these two lines are responsible for running the actual simulation (for the time t = 0s to t = 4.2s), and then write the resulting curves into the file throw-vertically.svg. And here it is, without further ado:

integration of vertical throw

The blue line is the height (in meter), and the yellow line the velocity (in meter/second). Positive velocities mean that the stone is moving upwards, negative that it's moving downwards. After about 4 seconds the stone has the height with which it started, at a velocity of about -20m/s. You don't see any effect of the stone hitting the ground, because the model knows nothing about a ground located at a height of 0m. Just imagine the stone fell into a well or down a cliff, and thus can have negative height too.

Iterating: throwing a stone at an arbitrary angle

It gets a bit more involved when you consider not only the y direction, but also the x direction, and throw the stone at an arbitrary angle. Still the x and y axis are rather independent:

use v6;
use Math::Model;

for 30, 45, 60 -> $angle {

    my $m = Math::Model.new(
        derivatives => {
            y_velocity      => 'y',
            y_acceleration  => 'y_velocity',
            x_velocity      => 'x',
        },
        variables   => {
            y_acceleration  => { $:force / $:mass },
            mass            => { 1 },           # kg
            force           => { -9.81 },       # N = kg m / s**2
            x_velocity      => { 20 * cos($angle, Degrees) } # m / s
        },
        initials    => {
            y               => 0,               # m
            y_velocity      => 20 * sin($angle, Degrees),    # m/s
            x               => 0,               # m
        },
        captures    => <y x>,
    );

    $m.integrate(:from(0), :to(2 * 20 * sin($angle, Degrees) / 9.81), :min-resolution(0.2));
    $m.render-svg("throw-angle-$angle.svg", :x-axis<x>,
                  :width(300), :height(200),
                  :title("Throwing at $angle degreees"));
}

The x velocity stays approximately constant (we disregard air drag), and it's value is the cosine of the throwing angle times the initial, total velocity. The velocity in y direction is the sine of the throwing angle times the initial, total velocity.

As a trick to get nicer graphs in the end, I calculated the expected time until it hits the ground (which I know to be 2 * v_y / a; this is cheating, but it doesn't change the physics behind it).

Finally this time we don't want to have the elapsed time on the x axis, but the actual position in x direction. That can be done with the :x-axis<x> option.

integration of throw at 30 degrees
integration of throw at 45 degrees
integration of throw at 60 degrees

(Note that I cheated to produces these charts; normally SVG::Plot, the module that produces these graphs, automatically scales the axis; I've manually suppressed that; if you try to out the example you'll see that the three charts look much the same, except for different axis scaling).

The maximum reach in x direction before hitting the ground is achieved at 45 degrees. For smaller angles it's not long enough in the air, and for larger angles too much of the velocity is "wasted" in the vertical direction, so the stone doesn't get very far.

A third model: oscillating spring

Finally I want to present a third, simple model: a mass hanging down from a spring, this time including air drag. It doesn't show off any new features of Math::Model, but the result is a nice, oscillating curve.

use v6;
use Math::Model;

my $m = Math::Model.new(
    derivatives => {
        velocity     => 'height',
        acceleration => 'velocity',
    },
    variables   => {
        acceleration    => { $:force / $:mass },
        mass            => { 1 },
        force           => { - $:height - 0.2 * $:velocity * abs($:velocity)},
    },
    initials    => {
        height      => 1,
        velocity    => 0,
    },
    captures    => <height>,
);

$m.integrate(:from(0), :to(20), :min-resolution(1));
$m.render-svg('spring.svg', :title('Spring with damping'));

The air drag/damping is built into the formula for the force. It is proportional to the square of the velocity (making analytical solutions a nuisance), and always points in the opposite direction as the velocity.

oscillation of a spring with air drag

Moving on

If you want to have some fun with Math::Model, here's a nice idea: You can simulate a mass attached to a spring, which can move freely in the xy plane. If you chose random initial values for the velocities in both directions, you can get non-periodic (chaotic?) trajectories in the xy plane.

(If you do, please send me the model so that I can also play with it :-))

A personal note

Ever since I've used the simulation tool "stella" in school (must have been year 2002 or so), I've wanted to write something similar. Math::Model is it. It was quite fun to implement in Perl 6. The only drawback is that it's quite slow.

Perlsphere: CPANdeps

<a href="http://cpandeps.cantrell.org.uk/">CPANdeps</a> now lets you filter test results by perl version number, and also knows what modules were in core in which versions of perl. Hurrah!

Perlsphere: YAPC::Europe 2007 report: day 2

A day of not many talks, but lots of cool stuff. Damian was his usual crazy self, and MJD's talk on building parsers was really good. Although I probably won't use those techniques at work as functional programming seems to scare people.<p>The conference dinner at a <a href="http://wikiproxy.cantrell.org.uk/Heuriger">Heuriger</a> on the outskirts of Vienna was great. The orga-punks had hired a small fleet of buses to get us there and back, and one of the sponsors laid on a great buffet. The local wine was pretty damned fine too, and then the evening de-generated into Schnapps, with toasts to Her Majesty, to her splendid navy, and to The Village People.<p>It wasn't all debauchery in the evening though - on the bus, I had a very useful chat with <a href="http://www.bruhat.net/">Philippe</a> about <a href="http://search.cpan.org/~book/Net-Proxy-0.08/">Net::Proxy</a>, and re-designing it to make it easier to create new connectors for it.

Perlsphere: YAPC::Europe 2006 report: day 3

There were quite a few interesting talks in the morning, especially Ivor's one on packaging perl applications. Oh, and mine about rsnapshot, of course, in which people laughed at the right places and I judged the length of it just right, finishing with a couple of minutes left for questions.<p>At the traditional end-of-YAPC auction, I avoided spending my usual stupid amounts of money on stupid things, which was nice. Obviously the hundred quid I put in to buying the hair style of next year's organisers wasn't stupid. Oh no. Definitely not.<p>An orange mohican will suit <a href="http://static.flickr.com/9/11370395_031596292a_m.jpg">Domm</a> beautifully.

Perlsphere: YAPC::Europe 2007 report: day 3

My <a href="http://www.justanotherperlhacker.org/lightning/index.shtml">Lightning Talk</a> on <a href="http://cpandeps.cantrell.org.uk/">cpandeps</a> went down really well, although as Jos&eacute; pointed out, I need to fix it to take account of <a href="http://cpandeps.cantrell.org.uk/?module=File%3A%3ACopy">File::Copy</a> being <a href="http://abigail1.hates-software.com/2005/09/21/0692681a.html">broken</a>. I also need to talk to Domm after the conference is over to see if I can get dependency information from CPANTS as well as from META.yml files.<p>There were lots of other good lightning talks. Dmitri Karasik's regexes for doing OCR, Juerd Waalboer's <a href="http://search.cpan.org/~juerd/Unicode-Semantics-1.00/">Unicode::Semantics</a>, and Ren&eacute;e B&auml;cker's <a href="http://search.cpan.org/~ctrondlp/Win32-GuiTest-1_50.5/">Win32::GuiTest</a> were especially noteworthy.<p>Richard Foley's brief intro to the perl debugger was also useful. Unfortunately Hakim Cassimally's talk was about debugging <em>web</em> applications, which I'd not noticed on the schedule, so I didn't stay for that.<p>And finally, Mark Fowler's grumble about why perl sucks (and what to do about it) had a few interesting little things in it. I am having vaguely sick ideas about mixing some of that up with an MJD-stylee parser.<p>At the auction I paid &euro;250 to have the Danish organisers of next year's YAPC::Europe wear the Swedish flag on their foreheads. This, I should point out, was <a href="http://drinkbroken.typepad.com/">Greg</a>'s idea. I would never be so evil on my own.

Perlsphere: Currying

NAME

"Perl 5 to 6" Lesson 28 - Currying

SYNOPSIS

  use v6;
  
  my &f := &substr.assuming('Hello, World');
  say f(0, 2);                # He
  say f(3, 2);                # lo
  say f(7);                   # World
  
  say <a b c>.map: * x 2;     # aabbcc
  say <a b c>.map: *.uc;      # ABC
  for ^10 {
      print <R G B>.[$_ % *]; # RGBRGBRGBR
  }

DESCRIPTION

Currying or partial application is the process of generating a function from another function or method by providing only some of the arguments. This is useful for saving typing, and when you want to pass a callback to another function.

Suppose you want a function that lets you extract substrings from "Hello, World" easily. The classical way of doing that is writing your own function:

  sub f(*@a) {
      substr('Hello, World', |@a)
  }

Currying with assuming

Perl 6 provides a method assuming on code objects, which applies the arguments passed to it to the invocant, and returns the partially applied function.

  my &f := &substr.assuming('Hello, World');

Now f(1, 2) is the same as substr('Hello, World', 1, 2).

assuming also works on operators, because operators are just subroutines with weird names. To get a subroutine that adds 2 to whatever number gets passed to it, you could write

  my &add_two := &infix:<+>.assuming(2);

But that's tedious to write, so there's another option.

Currying with the Whatever-Star

  my &add_two := * + 2;
  say add_two(4);         # 6

The asterisk, called Whatever, is a placeholder for an argument, so the whole expression returns a closure. Multiple Whatevers are allowed in a single expression, and create a closure that expects more arguments, by replacing each term * by a formal parameter. So * * 5 + * is equivalent to -> $a, $b { $a * 5 + $b }.

  my $c = * * 5 + *;
  say $c(10, 2);                # 52

Note that the second * is an infix operator, not a term, so it is not subject to Whatever-currying.

The process of lifting an expression with Whatever stars into a closure is driven by syntax, and done at compile time. This means that

  my $star = *;
  my $code = $star + 2

does not construct a closure, but instead dies with a message like

  Can't take numeric value for object of type Whatever

Whatever currying is more versatile than .assuming, because it allows to curry something else than the first argument very easily:

  say  ~(1, 3).map: 'hi' x *    # hi hihihi

This curries the second argument of the string repetition operator infix x, so it returns a closure that, when called with a numeric argument, produces the string hi as often as that argument specifies.

The invocant of a method call can also be Whatever star, so

  say <a b c>.map: *.uc;      # ABC

involves a closure that calls the uc method on its argument.

MOTIVATION

Perl 5 could be used for functional programming, which has been demonstrated in Mark Jason Dominus' book Higher Order Perl.

Perl 6 strives to make it even easier, and thus provides tools to make typical constructs in functional programming easily available. Currying and easy construction of closures is a key to functional programming, and makes it very easy to write transformation for your data, for example together with map or grep.

SEE ALSO

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

http://hop.perl.plover.com/

http://en.wikipedia.org/wiki/Currying

Perlsphere: The Perl Survey and Perl 6

Today I've participated in The Perl Survey, and I want to encourage you to do the same.

I was a bit disappointed that the list of Perl versions didn't include any Perl 6 - which I use sufficiently to mark that option if it existed.

It's a sad fact that parts of the Perl community haven't realized that Perl 6 is more than a dream, but comes with programs you can run today. Association with or funding from TPF doesn't seem to make you immune to that misconception.