Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Alias (5735)

Alias
  (email not shown publicly)
http://ali.as/

Journal of Alias (5735)

Wednesday September 08, 2010
09:11 PM

DBD::SQLite 1.31 releasing next week and may break your code

After 6 or 7 months (mainly waiting around for the next "recommended upgrade instruction" from the SQLite project) the latest DBD::SQLite release should occur next week.

You can get the 1.30_06 release candidate from the CPAN, or from the following URL if your mirror hasn't synced yet.

http://svn.ali.as/cpan/releases/DBD-SQLite-1.30_06.tar.gz

Apart from the normal batch of SQLite upgrades (from 3.6.22 to 3.7.2), bug fixes, and minor enhancements, this release has two changes that may break your code.

These changes have been in the dev releases for some time, but you may want to take the opportunity to test more intensively if you use either of the following features.

1. BLOB columns with UTF8 content

- Resolved #54271: Inserting a string with utf-8 flag on
  corrupts BLOB data; now BLOB data is always stored as bytes
  (without the utf-8 flag) even if it has the flag set (ISHIGAKI)

2. FTS3 queries

- Added support for FTS3 tokenizers written in Perl. Added tests
  and documentation on how to use FTS3. Changed compilation flag
  to use the recommanded -DSQLITE_ENABLE_FTS3_PARENTHESIS
  *** MAY POSSIBLY BREAK OLD APPLICATIONS THAT ALREADY USED FTS3 ***
  (DAMI)

If you are currently using FTS3, please see DBD::SQLite::FTS3Transitional which contains a helper function for automatically upgrading old FTS3 queries to the new syntax.

Sunday September 05, 2010
09:26 PM

Should Module::Install move to explicit plugin declaration?

Module::Install has been through a long period of gradual stability over the last year, without any really dramatic improvements to the grammar or APIs.

With the more urgent "it doesn't work with blah" stuff mostly solved now, one of the big remaining issues is around error clarity and excessive magic.

For example, some random author that is trying to checkout a Catalyst project needs:

1. To have Module::Install installed.
2. To have Module::Install::Catalyst installed.

In the case of the former, you get the semi-cryptic but at least standard "Can't find inc/Module/Install.pm in @INC" message, so the error is resolvable.

But in the latter case, you're likely to get something like "Unknown command 'catalyst_ignore'", with no real obvious resolution mechanism.

I think this idea of automatic plugin discovery is starting to hit it's limits in terms of clarity.

And so I'd like to do something counter to my natural instincts here, and make M:I more verbose.

I'm thinking of something like the following for explicitly declaring the use of a non-core Module::Install extension.

use inc::Module::Install qw{ Catalyst XSUtil };

This would both allow M:I to error with a much more meaningful error when you don't have a plugin, and also prevent the loading of unused plugins which should prevent accidental plugin collisions (some of which I've seen occurring in the CPAN Testers machines).

Thoughts?

Thursday August 19, 2010
10:20 PM

Speaking at Microsoft TechEd - Any issues you want raised?

Next week I will at Microsoft's TechEd Australia event, courtesy of Microsoft Australia and Microsoft Open Source Labs.

More specifically, I'll be attending the Open Source mini-conf and discussion day on Tuesday, and presenting in the Community Presentations to Microsoft session on the current state of Perl and Windows on Wednesday.

Likely topics will include a review of the first year of the CPAN Testing Lab and a second-generation based on their Cloud Services, free code signing certificates for open source developers, and what issues are slowing us down or blocking progress.

So consider this your opportunity to raise any outstanding issues you have with Microsoft and Perl. What problems are you still seeing, what would like fixed or changed, and what is on your want-to-have list?

I'll try to address as many of your issues as possible in the time I have available with them (which is actually pretty substantial).

Sunday August 15, 2010
10:04 PM

Class::XSAccessor now even faster'er

The new 1.07 release of Class::XSAccessor mentions the use a new somewhat-evil technique for making the code even faster than it was previously.

But how much faster is it?

The following are being run on a fairly typical corporate Windows XP machine, with Strawberry Perl 5.10.1 and thread support.

First, some benchmarks using the previous 1.05 release (two runs)

Benchmark: timing 10000000 iterations of accessor_get, accessor_set, constructor, false, getter, predicate, setter, true...
accessor_get:  1 wallclock secs ( 2.51 usr +  0.00 sys =  2.51 CPU) @ 3976143.14/s (n=10000000)
accessor_set:  2 wallclock secs ( 3.09 usr +  0.00 sys =  3.09 CPU) @ 3233107.02/s (n=10000000)
constructor: 16 wallclock secs (15.67 usr +  0.00 sys = 15.67 CPU) @ 638080.65/s (n=10000000)
     false:  2 wallclock secs ( 1.91 usr +  0.00 sys =  1.91 CPU) @ 5243838.49/s (n=10000000)
    getter:  1 wallclock secs ( 2.34 usr +  0.00 sys =  2.34 CPU) @ 4266211.60/s (n=10000000)
  predicate:  1 wallclock secs ( 2.38 usr +  0.00 sys =  2.38 CPU) @ 4210526.32/s (n=10000000)
    setter:  2 wallclock secs ( 3.27 usr +  0.00 sys =  3.27 CPU) @ 3061849.36/s (n=10000000)
      true:  1 wallclock secs ( 1.80 usr +  0.00 sys =  1.80 CPU) @ 5564830.27/s (n=10000000)
 
Benchmark: timing 10000000 iterations of accessor_get, accessor_set, constructor, false, getter, predicate, setter, true...
accessor_get:  3 wallclock secs ( 2.51 usr +  0.00 sys =  2.51 CPU) @ 3976143.14/s (n=10000000)
accessor_set:  3 wallclock secs ( 3.14 usr +  0.00 sys =  3.14 CPU) @ 3183699.46/s (n=10000000)
constructor: 15 wallclock secs (15.73 usr +  0.00 sys = 15.73 CPU) @ 635566.29/s (n=10000000)
     false:  2 wallclock secs ( 1.86 usr +  0.00 sys =  1.86 CPU) @ 5379236.15/s (n=10000000)
    getter:  3 wallclock secs ( 2.50 usr +  0.00 sys =  2.50 CPU) @ 4000000.00/s (n=10000000)
  predicate:  3 wallclock secs ( 2.47 usr +  0.00 sys =  2.47 CPU) @ 4050222.76/s (n=10000000)
    setter:  4 wallclock secs ( 3.13 usr +  0.00 sys =  3.13 CPU) @ 3200000.00/s (n=10000000)
      true:  2 wallclock secs ( 1.98 usr +  0.00 sys =  1.98 CPU) @ 5037783.38/s (n=10000000)

And now again with the new 1.07 release.

Benchmark: timing 10000000 iterations of accessor_get, accessor_set, constructor, false, getter, predicate, setter, true...
accessor_get:  2 wallclock secs ( 1.75 usr +  0.00 sys =  1.75 CPU) @ 5711022.27/s (n=10000000)
accessor_set:  1 wallclock secs ( 2.69 usr +  0.00 sys =  2.69 CPU) @ 3721622.63/s (n=10000000)
constructor: 15 wallclock secs (15.62 usr +  0.00 sys = 15.62 CPU) @ 640000.00/s (n=10000000)
     false:  1 wallclock secs ( 1.28 usr +  0.00 sys =  1.28 CPU) @ 7806401.25/s (n=10000000)
    getter:  1 wallclock secs ( 1.56 usr +  0.00 sys =  1.56 CPU) @ 6397952.66/s (n=10000000)
  predicate:  2 wallclock secs ( 1.92 usr +  0.00 sys =  1.92 CPU) @ 5205622.07/s (n=10000000)
    setter:  3 wallclock secs ( 2.50 usr +  0.00 sys =  2.50 CPU) @ 4000000.00/s (n=10000000)
      true:  2 wallclock secs ( 1.55 usr +  0.00 sys =  1.55 CPU) @ 6464124.11/s (n=10000000)
 
Benchmark: timing 10000000 iterations of accessor_get, accessor_set, constructor, false, getter, predicate, setter, true...
accessor_get:  2 wallclock secs ( 1.78 usr +  0.00 sys =  1.78 CPU) @ 5614823.13/s (n=10000000)
accessor_set:  3 wallclock secs ( 2.63 usr +  0.00 sys =  2.63 CPU) @ 3809523.81/s (n=10000000)
constructor: 16 wallclock secs (15.69 usr +  0.00 sys = 15.69 CPU) @ 637429.88/s (n=10000000)
     false:  2 wallclock secs ( 1.22 usr +  0.00 sys =  1.22 CPU) @ 8203445.45/s (n=10000000)
    getter:  2 wallclock secs ( 1.53 usr +  0.00 sys =  1.53 CPU) @ 6535947.71/s (n=10000000)
  predicate:  2 wallclock secs ( 1.78 usr +  0.00 sys =  1.78 CPU) @ 5614823.13/s (n=10000000)
    setter:  2 wallclock secs ( 2.56 usr +  0.00 sys =  2.56 CPU) @ 3903200.62/s (n=10000000)
      true:  2 wallclock secs ( 1.48 usr +  0.00 sys =  1.48 CPU) @ 6738544.47/s (n=10000000)

The numbers are pretty impressive.

The 'accessor', 'setter', 'predicate' and 'true' methods are about 25% faster, while 'getter' is a whopping 60% faster and (curiously) 'false' is about 50% faster as well.

Constructors are really the only thing that hasn't changed.

Impressive work, even if the code is a bit risky.

Saturday August 14, 2010
08:39 PM

Why does Object::Tiny only support getters

http://perlalchemy.blogspot.com/2010/08/objecttinyrw-and-moosexnonmoose.html

Zbigniew Lukasiak tries out Object::Tiny and wonders why it is that I didn't allow for the creation of setters when it is only a one line change.

Like most ::Tiny modules the reason is a bit complex and the result of compromises.

Object::Tiny began as an attempt to create a lighter, faster, version of Class::Accessor. A way to bulk-generate the accessor code I had to type over and over again.

However, where I differ is a strong preference for light and elegant API design.

And so I decided to implement mine with as little implementation code as possible, and as little API code as possible.

Once you have decided to go down the simplicity path, there's a couple of standard techniques you often end up using.

The first and most important is state reduction.

In their introduction to Erlang, the founders of that language describe state as one of the main sources of failures in programs. And so anything that removes state, at the very least unnecessary state, is a positive. Especially if the state reduction also results in code reduction, and a reduction in computation.

So take the following example, where we create an object with some attributes and then run some code that will use those object attributes..

my $object = Class->new;
$object->foo(1);
$object->bar(2);
$object->do_something;

This is a use case that we see fairly often, but it's really quite horrible code. It is really only the object-oriented equivalent of something like the following.

our $Object::foo = 1;
our $Object::bar = 2;
do_something('Object');

It is especially bad code if the following code would throw an exception.

my $object = Class->new;
$object->do_something;

If this blows up, then you are REALLY doing something wrong, because you have allowed the creation of completely invalid objects. Now anybody taking one of these objects as a parameters needs to do with following.

sub foo {
    my $object = shift;
    unless (
        $object->isa('Class')
        and
        defined $object->foo
        and
        $object->foo > 0
        and
        defined $object->bar
        and
        $object->bar > 2
    ) {
        die "Invalid object";
    }
}

If you are going to create an object for something, you HAVE to be sure that the objects are trustworthy.

And so you should never allow objects to exist that are invalid. EVERY object should be a valid object.

At the absolute minimum objects should be able to default every attribute to something reasonable and unlikely to cause problems.

But this still results in excess and wasteful work, because the object has to transition through two or more states.

You start with an object with parameters and defaults, and you validate them. And then you change on of the attributes immediately, validating it AGAIN. In the mean time, your object exists in a state that it will never actually be used in.

And so everywhere you possibly can, you should be setting attributes in the constructor rather than afterwards.

my $object = Class->new(
    foo => 1,
    bar => 2,
);
$object->do_something;

Less state, less complexity, less CPU, and less bugs.

If we accept this model of pushing all the configuration into the object up front to reduce state, then why change the object arbitrarily?

In fact, anything that you ARE going to change should be done under very controlled conditions.

It should require a dedicated method to apply the change, it should require validation, and work. It shouldn't be trivial, and it shouldn't be automatic.

If I had my way, Moose would set is => 'ro' by default, to make people think before they go about simply allowing stuff to change.

It also happens to let you shrink down the API markedly.

There are three potential use cases available when implementing accessors. Everything readonly, everything readwrite, or mixed.

With Object::Tiny, I was aiming for the smallest possible code.

Implementing either all-readonly or all-readwrite can be done with the following.

use Class qw{
    foo
    bar
};

By contrast, if we want to allow mixed readonly and readwrite, we would need some way of distinguishing. Something like the following.

use Class {
    readonly => [ 'foo' ],
    readwrite => [ 'bar' ],
};
 
use Class [ qw{
    foo
} ], [ {
    bar
} ];
 
use Class {
    foo => 'ro',
    bar => 'rw',
};

No matter how you try, there's always an inherent additional element of complexity that results from the split between them.

And so the decision to go with all-readonly in Object::Tiny is a combination of these two issues.

If went with all-readwrite, I'm practically encouraging bad behaviour and more bugs. If I went with mixed accessors, the API would remain relative complex.

In the end, the best way to achieve both API simplicity and code safety is to only provide read-only accessors, and anything more complex should require both though and effort.

Wednesday August 04, 2010
12:40 AM

Trailer Theory - Reinvented for Ignite Sydney as Economics

Back in 2005 in only my fifth use.perl post ever, I outlined an idea I had been developing for a couple of years that I called "Trailer Theory".

A few years ago on my Portable Perl world hack'a'tour, I took with me a lightning talk version of the concept. It was a pretty crude talk but was received, it seemed, fairly well by the development community.

Since that trip, and inspired by the unexpected conversion of my "Perl is unparsable" claims in the PPI docs into a formal mathematical proof (complete with "Kennedy's Lemma") I've been wondering if this "Trailer Theory" idea could really be developed as a proper scientific proof, and if so what would that look like.

A couple of months ago I presented a new version of the talk at Ignite Sydney, speaking to an mixed audience of Twitterati, social media, advertising and journalist types.

I've rebuilt the talk from scratch and tried to outline the same idea, but in the form of a kind of layman's Economics Proof.

I hope you enjoy the result.

Adam Kennedy - Using Economics to make movies suck less


Notes for other speakers:

1. Ignite advances slides every 15 seconds, no clickers allowed. This turns out to take a shitload of practice to get right.

2. When someone says to you "Here's your mark, you need to stay on this line to be in the fixed spot" it helps to pay attention. FAIL :)

Tuesday August 03, 2010
12:09 AM

Protesting the Moose with sugary alternatives

At work, we've been experimenting with Moose because in our enormous and complex codebase we think we can probably benefit a lot from the extra rigour that it brings.

Before I continue, let me note that ours is a typical mod_perl enterprise setup with 6gig of memory per machine, so any memory consumed before the Apache fork is essentially free.

So none of the issues people (including me) have with startup code and memory consumption apply in this case, and I won't be addressing performance issues in this post.

The consensus of the half-dozen people at work is how Moose tries to look like a declarative extension, but doesn't actually act like it.

The following is what Moose seems to have been aiming for.

package Foo;
 
use Moose;
 
extends 'Bar';
with    'Role1';
with    'Role2';
 
has this => (
    is  => 'ro',
    isa => 'Str',
);
 
has that => (
    is  => 'ro',
    isa => 'Str',
);
 
1;

Unfortunately, this is what we've had to do instead.

package Foo;
 
use Moose;
 
BEGIN { # When we use Catalyst
    extends 'Bar';
}
 
has this => (
    is  => 'ro',
    isa => 'Str',
);
 
has that => (
    is  => 'ro',
    isa => 'Str',
);
 
with    'Role1';
with    'Role2';
no Moose;
__PACKAGE->meta->make_immutable;

This "real Moose" code totally spoils the dream of what we felt like we were going to get when we started to play with it.

Most of our current options for fixing this amount to either.

a) Add this extra dependency that will unscrew one of the other of the problems (namespace::autoclean)

b) Use this SECOND heavy sugar layer on top of the FIRST sugar layer, on top of Class::MOP.

Is fixing the syntax or writing light weight sugar really so hard?

As a kind of protest, I tried it for myself and managed to create MooseX::Atom.

This still has some flaws, but the current equivalent of the above would just be this.

package Foo;
 
use MooseX::Atom [
    extends => 'Bar',
    with    => 'Role1',
    with    => 'Role2',
    has     => [
         this => (
             is  => 'ro',
             isa => 'Str',
         ),
    ],
    has     => [
         that => (
             is  => 'ro',
             isa => 'Str',
         ),
    ]
];
 
1;

You can do the same thing for roles with MooseX::Role::Atom.

Now clearly, this might have some issues. It's the work of an hour and not a whole lot of thought.

But it's still light and clean, with all the class spec in one place up the top where people are used to seeing the declarative stuff in Perl modules.

Perhaps something like this might be a little better...

package Foo;
 
use MooseX::Hash {
    extends => 'Bar',
    with    => [ 'Role1', 'Role2' ],
    default => { is => 'ro' },
    has     => {
        this => { isa => 'Str' },
        that => { isa => 'Str' },
    },
);
 
1;

Thursday July 29, 2010
08:23 AM

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.

Sunday July 25, 2010
07:55 AM

For people running Perl conferences

Leo Lapworth comments in "For speakers at Perl conferences" that you should record your own talks at conferences, because organisers cannot be trusted to release the videos they take of you.

I wholeheartedly agree. I've spoken at numerous conferences, including several large ones, and only in about 10-20% of cases have the videos of me EVER appeared.

I'm amazed that conference organisers can put in so much effort into recording (dozens of tapes, multiple cameras, multiple operators) and then never produce anything as a result.

The only time I'm aware of that a full talk of mine has appeared online was at a Linux.conf.au, who had a dedicated video team of eight people.

Where is all this footage, and why does it never get processed? Why even bother recording it? If you don't have time, send me the raw tape of my own talk and I will do it myself if needed.

YAPC::NA? You listening?

Thursday July 22, 2010
10:53 PM

A reminder - Padre Second Birthday Hackathon this weekend

This is just a quick reminder that this weekend is the Padre's second birthday party and hackathon.

If you are a Padre user, please drop in and say hello to the team. We'd love to hear how you are using Padre and where your main needs are for the next year.

If you are interested in trying out Padre for the first time, or trying your hand at improving it for the first time, it's a great time to get started because we'll have plenty of people around to provide guidance and advice.

Some of the plans for this weekend are to bring all the plugins up to date with the latest versions of the plugin API, to start the merge of the ConfigSync branch, and if we can, to start on the Madre server that will serve as the ConfigSync and Telemetry server for Padre.

I look forward to seeing you there!