Florian Ragwitz: Declaring Catalyst Actions
For a long time the Catalyst Framework has been using code attributes
to allow users to declare actions that certain URLs get dispatched to.
That looks something like this:
sub base : Chained('/') PathPart('') CaptureArgs(0) ... sub index : Chained('base') PathPart('') Args(0) ... sub default : Chained('base') PathPart('') Args ...It's a nice and clean syntax that keeps all important information right next to the method it belongs to. However, attributes in perl have a couple of limitations. For one, the interface the perl core provides to use them is horrible and doesn't provide nearly enough information to do a lot of things, but most importantly attributes are just plain strings. That means you will need to parse something like
"Chained('base')" into
(Chained => 'base') yourself to make proper use of them.
While that's easy for the above example, it can be very hard in the
general case because only perl can parse Perl. It's one of the reasons
you can't use Catalyst::Controller::ActionRole to apply
parameterized roles to your action instances, because parsing
parameters out of things like
Does(SomeRole => names => [qw/affe tiger/], answer_re => qr/42/ )
would be awful and wrong.
With Catalyst 5.8 most of the attribute related code has been removed
from the internals. It's now using MooseX::MethodAttributes to do
all the heavy lifting. Also the internals of how actions are
registered have been refactored to make it easier to implement
alternate ways without changing the Catalyst core.
As a proof of concept for this I implemented a new way of declaring
actions that's very similar to how Moose provides it's sugar
functions. You can get it from
github.
With that, the above example looks like this:
action base => (Chained => '/', PathPart => '', CaptureArgs => 0) => sub ... ; action index => (Chained => 'base', PathPart => '', Args => 0 ) => sub ... ; action default => (Chained => 'base', PathPart => '', Args => undef) => sub ... ;It also moves method declaration from compiletime to runtime, making this possible:
for my $action (qw/foo bar baz/) action $action => (Chained => 'somewhere', Args => 0) => sub my ($self, $ctx) = @_; $ctx->stash-> $action = $ctx->model('Foo')->get_stuff($action); ;Admittedly, that's all very ugly, but illustrates well what kind of things we're able to do now. But it doesn't need to be ugly. With Devel::Declare we have a great tool to add our own awesome syntax to perl, similar to how things like MooseX::Method::Signatures, MooseX::MultiMethods and MooseX::Declare do. So how would a declarative syntax for Catalyst controllers look like? I don't know. Ideas include something like this:
under /some/where, action foo ('foo', $id) ...to mean:
sub foo : Chained('/some/where') PathPart('foo') CaptureArgs(1) ...Adding Moose type constraints to this would be interesting, too, and make validation of captures and arguments a lot easier. Multi dispatch similar to MooseX::MultiMethods could be handy as well:
under /some/where action ('foo', Int $id) # find and stash an item by id action ('foo', Str $name) # search items using $name action ('foo', Any $thing) # display error pageSo you see there are a lot of possibilities that should be explored. Unfortunately I have no idea what kind of syntax and features people would like to have, so your feedback on this would be much appreciated. :-)
After
Every PulseAudio "Sink" has a "Source" named "monitor". This lets you attach to a given Sink and chain more stuff to it, for example, recording the audio that is playing through PulseAudio at any given moment. This is very handy for creating, for example, PubQuiz-style clips of songs, movies, etc.
Here is a script to find the monitor for the most recently added Sink, record from it, and shove it through "sox" to get a WAV instead of raw sound data (requires recent sox, Pulse, etc):
This is a continuation from
Reportbug-NG s ability to filter and sort bugreports in various ways can greatly help triaging bugreports after a certain criterion.
In this example I use the bugs of the KDE team, because they have quite a lot of bugs and are currently on a bug triage.
Two releases ago I tried to help them cleaning their BTS from obsolete bugeports. My tactic back then was to find bugreports where no action has been taken for a long time. I noticed that there was no easy way to find such bugs since neither reportbug nor the BTS allowed to sort the bugs this way, so finding the candidates I searched for was very cumbersome.
So let s try to find those bugs with rng: To get all bugs belonging to the KDE team start rng with the maintainer as argument:
I've
Do you listen to the radio?
I don t, and there are multiple reasons for that:
First and foremost, I don t like the music they play these days.
Even though there are stations which will occasionally play a more
eclectic tune, the Swiss government does not, to my knowledge,
dictate any quota, like New Zealand actually requires stations to
broadcast New Zealand music at least 20% of the time.
The result is music made by producers, who stand pop icons with
little clothing in front of microphones, instruct them to move
their bodies in obscene ways, and coach them to croak songs someone
else wrote en masse in some basement somewhere. All those
songs sound alike.
To ensure a constant supply of pop dolls, they hype television
shows with titles such as Germany s seeks the next superstar ,
when most of Germany actually couldn t care less, and only those
with vacuous brain capacity follow with excitement, because they
wouldn t know what else to do.
Second, I don t have the time or energy to listen to discussion
rounds on the radio, especially not when topic are about
society , which noone can define in the first place.
Over the Easter holidays, I finally did a bit of real
programming again, adding some quantum chemistry related C++
code to 
I've started to develop