by Tobias Rundström (noreply@blogger.com) at March 08, 2010 04:02 AM
by Tobias Rundström (noreply@blogger.com) at March 08, 2010 04:02 AM
…pues eso, que ya no solo pertenezco a Planet Linux México, o Planet XMMS2 si no que recién iniciado el Planet Python México me integre y me siento muy contento de pertenecer a Planetas donde cubran temas que son de mi completo interés y les agradezco a todos por tomar en cuenta mi humilde blog.
Planet Linux México
Planet XMMS2
Planet Python México
by Tobias Rundström (noreply@blogger.com) at February 21, 2010 12:30 PM
by Tobias Rundström (noreply@blogger.com) at February 20, 2010 02:39 PM
by Tobias Rundström (noreply@blogger.com) at February 20, 2010 01:39 AM
Sin embargo, he considerado que ha sido una buena forma de entretenerme aplicando algunos conocimientos hasta ahora estancados por cosas del trabajo y escuela. Me he divertido de lo lindo; aprendí muchas cosas que solo tenía en concepto, pero, que no había tenido la molestia de sentarme a practicarlas.
Y sacandole un poco de jugo a esta sencilla aplicación decidí darle algunos toques mas:
De entre las cosas que estuve aprendiendo (y que aun lo estoy por que es constante) fue el uso de las librerías gráficas wx para las GUI’s sobre python, y ya que heredan mucho de C, la cosa pues puede parecer tan fácil o complicado según se vea.
Como muchos desarrolladores me valí de wxGlade para el diseño de las interfaces que poco después se pueden mejorar en rendimiento codificando a mano (gracias a mi querido gEdit + plugins) y que puede ahorrarnos mucho tiempo.
En cuanto a la programación pues verán, el uso del middleware python-xmmsclient es básicamente sencillo, salvo claro que para capturar los cambios en el reproductor (cambio de canción) fue necesario implementar llamadas asíncronas con el servidor para después darles salida a twitter.
Otro aspecto que me pareció interesante manejar fue el uso de archivos de configuración, y ya que python cuenta con algunas librerías que nos facilitan el trabajo, no dude en usarlas. ConfigPaser es una librería que me permite editar los archivos de configuración de manera natural, sin rodeos pues y de la que recomiendo le den una checada.
Y por último pero sin dejar de lado, el uso de la clase TaskBarIcon de wx para implementar un icono en la barra de tareas el cual al dar doble click me permite visualizar la app, o click derecho para un Menú con algunas acciones como las que podemos ver en las imágenes.
Pongo a disposición de ustedes el código, ya sea para su uso, desarrollo, o simplemente por curiosidad de ver lo que ya detrás del desarrollo con Python, wx, XMMS2 y Twitter.
svn checkout http://x2t.googlecode.com/svn/trunk/ x2t-read-only
Parametros:
En algunas ocasiones se me ha ocurrido “quiero twittear lo que estoy escuchando”, y me refiero a algo automático para que no tenga que escribirlo yo mismo.
Así que decidí programar una pequeña aplicación que lo haga, que tenga la bondad de darme a elegir si esta activa o inactiva, o bien establecer el formato en el que deseo que aparezca en twitter; así que hice manos a la obra y comencé a programarlo.
La elección del lenguaje como muchos ya se podrán imaginar es Python, por lo que usare el middleware de python-xmmsclient.
La instalación obviamente involucra al servidor XMMS2 y xmmsclient así que podriamos hacerlo simplemente así.
# apt-get install xmms2 python-xmmsclientLo interesante aquí es el desarrollo de un cliente XMMS2, eficazmente sencillo, aunque encontrar información acerca de la librería puede resultar un poco complicado y al hacerlo es posible que para nuestra elección de lenguaje venga muy incompleta.
Pero esto no significa que no logremos adaptarnos fácilmente, es la ventaja de las api’s estandarizadas, así que nuestro primer paso será hacer conexión con el servidor.
Una conexión básica con el servidor sería:
#!/usr/bin/env python import xmmsclient import os import sys xmms = xmmsclient.XMMS("miCliente") try: xmms.connect(os.getenv("XMMS_PATH")) except IOError, detail: print "Conexión fallida:", detail sys.exit(1) result = xmms.playback_start() result.wait() if result.iserror(): print "Error al reproducir, %s" % result.get_error() else: sys.exit(0)
Como nos podemos dar cuenta, la conexión resulta muy sencilla, os.getenv(“XMMS_PATH”) nos devuelve el valor de la variable de entorno, y así nos permite saber si el servidor esta activo o no ya que al no estar corriendo, la variable no existe.
Por otro lado, una vez establecida la conexión podemos acceder a las acciones directamente del objeto xmms que creamos al iniciar el script, por ello, al ejecutar xmms.playback_start() le damos la orden al server de reproducir lo que tenga en cola, aunque no se ejecutará si no hasta haber llamado a xmms.wait().
Si por algún motivo no es posible reproducir algo, el objeto xmms arroja los errores (result.iserror()) que ocurrieron y así nosotros podemos controlarlos.
Podemos encontrar mas información sobre el desarrollo de clientes XMMS2 aqui por si estas interesado en ir mas a fondo, por mi parte trataré de ir con calma documentando lo que estoy desarrollando.
Una sugerencia podría ser desarrollar un pequeño engine de nuestro cliente, y así, hacernos la vida mas fácil para próximos desarrollos.
Hasta esta parte, todo ha ido claro me parece, aun no he tocado el tema de twitter así que ahora veremos algo al respecto.
Existen muchas librerías que podemos usar para nuestra aplicación, pero la que me sedujo fácilmente fue python-twitter (chales, eso fue un capumm). Python-Twitter es un proyecto que vienen desarrollando un grupo de developers, y resulta tan intuitiva que usarla será cosa de risa.
La librería viene incluida al igual que python-xmmsclient en los repos de Debian Lenny.
# apt-get install python-twitterY su uso es tan sencillo que el siguiente script resultará muy explicativo.
#!/usr/bin/env python # -*- coding: utf-8 -*- import twitter mytwitter = twitter.Api("miusuario","mipassword") status = mytwitter.PostUpdate('probando python-twitter') print status.text statuses = mytwitter.GetUserTimeline() for s in statuses: print s.text
Así es, importamos librería, creamos objeto, hacemos una publicación con el texto “probando python-twitter”, imprimimos lo que enviamos, pedimos el Timeline y lo iteramos imprimiendo los textos. Sencillo no ?
La documentación completa la podemos ver aquí.
Con esta información será posible el desarrollo del cliente x2t que tengo en mente, de hecho, he diseñado una pequeña interfaz que solo ocupara un mínimo de opciones como establecer nombre y password de twitter, un filtro el cual me permitirá definir el formato de mis tweets, y si esta activo o no el servicio.
Está es por ahora la propuesta.
Y por lo pronto esto es todo lo que puedo comentar, estaré trabando en este pequeño proyectito por las noches y espero no tardar demasiado en anunciar como ha quedado.
Today, i want to thanks the guys of Planet XMMS2 by add my feed. You know that i’m interested in developing for XMMS2 clients, and therefore i’m developing XMMS2 Client called Angel. Althought is developing even.
Thanks guys.
New XMMS2-Scrobbler release. Better than ever: multi-scrobbling is supported now. libre.fm users rejoice! See README for the details.
by Tilman Sauerbeck (tilman@code-monkey.de) at December 30, 2009 05:15 PM
by Tobias Rundström (noreply@blogger.com) at December 27, 2009 09:22 PM
For some mysterious reason, Internet Explorer (tested in IE7 and IE8) strips leading spaces in text nodes preceded by an empty element, such as this:
[code lang="html"]
[/code]
While innoccuous in static pages, it becomes problematic when DOM nodes get updated after a delay by some Javascript, as the separating whitespace has disappeared, hence ruining the layout of your text.
Surprisingly, I haven’t found any reference to this IE bug (not that there is a shortage of complaints about other IE idiosyncrasies), so I thought I’d share the problem and the solution I have found here. It’s all demonstrated in the following example:
[code lang="html"]
!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
[/code]
In the first case, the whitespace gets stripped, thus resulting in “Helloworld”. In the second example, the non-breaking space prevents IE from stripping the whitespace, so that when the span is filled by Javascript, the text reads “Hello world” as expected.
If you know other solutions or whether it’s considered a bug that will be fixed, please post in the comments!
On my way to the Google Summer of Code Mentor Summit 2009, I accepted DraX’s invitation to give a 1-hour talk about XMMS2 Collections at his work, i.e. Metaweb, in San Francisco.
The topic was somewhat relevant for them as it’s reminiscent of MQL, the query language they developed for Freebase. It’s worth noting that although both share a pool of buzzwords such as “graph”, “loosely-structured”, “querying”, etc, they are not quite the same:
Note: Collections 2.0 should however allow fancier querying to retrieve tree-shaped structures.
About 10-20 people showed up and listened to me blurbing about the concept of Collections, the rationale behind them, the API, Collections 2.0, possible UI uses, what it represents for the user, pointers to S4, etc.
It’s all in those over-engineered slides that I have no choice but to put online, under Creative Commons Attribution-Share Alike 2.5 License, for them to live on forever on the internets. And yes, it’s still either in evil Keynote format (source), or in PDF.
Oh and Metaweb, thanks for the food!
by Tobias Rundström (noreply@blogger.com) at September 23, 2009 05:27 AM
You've probably already heard of Sartak's awesome MooseX::Role::Parameterized.
As of version 0.25, MooseX::Declare provides some nice sugar for that. This is what it looks like:
use MooseX::Declare; role Counter (Str :$name) { has $name => (is => 'rw', isa => 'Int', default => 0); method "increment_${name}" { $self->$name( $self->$name + 1 ); } method "reset_${name}" { $self->$name(0); } } class MyGame::Weapon { with Counter => { name => 'enchantment' }; } class MyGame::Wand { with Counter => { name => 'zapped' }; }
Just thought I'd let you know, since i haven't gotten around to actually document this. In case you like it, have some spare tuits, and want to help out, the repository is right here :-)
by Florian Ragwitz (rafl@fsfe.org) at August 19, 2009 08:27 AM
IEEE Software recently published an opinion piece from Tom DeMarco titled ‘Software Engineering: An Idea Whose Time Has Come and Gone?’ in which DeMarco appears to declare the death of ‘Software Engineering’ as a discipline. Unsurprisingly, this is generating some waves in the tech blogging community, with pieces such as ‘Software Engineering: Dead?’ from Jeff Atwood’s Coding Horror, and Myles Eftos’s ‘Yep, Software Engineering is dead’.
From reading DeMarco’s article, it is apparent that what he is addressing is the emphasis placed on ‘control’ on software projects - that ‘software engineering’ is often taken to mean that it’s a means of controlling the outcomes of developing a software project. It should be obvious that DeMarco’s stance is one of reflecting upon his previous work and making some comments about how his work has been perceived in the software industry over the years. Aside from some “Aw shucks, I wish my younger self had been wiser†style reflection, DeMarco laments the fact that his work has been used over the years to justify the creeping bureaucratisation of the software development process. From that point, DeMarco goes on to prescribe that, rather than controlling minutiae, those in charge of software development should be treating their projects (by way of analogy) as unruly teenagers - by attempting to instil a sense of moral values and principles, rather than by being overbearing and all-controlling.
Unfortunately, Jeff & Myles appear to either be sensationalising, or reacting to a rather superficial reading of DeMarco’s opinion. Straight off the bat, Jeff points out DeMarco’s gravitas in his field, to hammer home the point that ‘yes, this is a big deal’. From there, however, Jeff switches to his usual agenda of elevating the romantic notion of ‘software craftsmanship’. Not that I’m averse to this position - au contraire, I’m a big fan of Jeff’s frequent expounding on matters of software development principles. What I disagree with, however, is the utter sensationalism with which this is being made here. At least, I am heartened that Jeff appears to have grasped the main point of DeMarco’s analogy: “If you want to move your project forward, the only reliable way to do that is to cultivate a deep sense of software craftsmanship and professionalism around it.â€
I have no idea what has been said about either DeMarco’s piece or Jeff’s blog post on the 220 mailing list, though reading through Myles’ blog post left me slightly incensed at certain points. The analogy between building a bridge and building software is somewhat tired. Compared to building bridges, building ‘software’ encompasses a vastly larger scope. That much we agree on. You might as well be comparing building software with building anything made of materials sourced from the ground. From here, however, it seems that Myles launches into a tirade about his least favourite academic subjects, or at least the ones that he found ‘stupid’. What I fail to grasp at this point is the relevance to DeMarco’s piece… But I’ll play along anyway.
Yes, formal proofs are arduous, and can be rather silly for trivial programming tasks, but it should be obvious that such techniques aren’t applicable to all software development contexts. Would you apply formal proof methods to a small dynamic website you’ve just built? Hell no. Would you apply formal proof methods to mission-critical software that could potentially lead to injuries, fatalities or serious damage to the environment or property, if anything were to go wrong? Hell yes. (Well, some variant of a formal method, anyway) It’s a simple cost-benefit (or risk analysis) scenario: which costs less - the development process, or the consequences of something going seriously wrong? I’d further argue that formal proof exercises done in an undergraduate academic setting would be more geared towards teaching and learning the process of doing the proofs than anything else. This is undergrad CS that we’re talking about, with its endless assortment of silly assignments that require students to produce little of value beyond the end of their courses. I might also add that, even with a ‘simple’ program having 9 lines of code, this degree of simplicity may be afforded by a myriad of much more complex underlying supporting systems - the degree of simplicity of a program may simply be a matter of perspective, or from where you’re standing to look at the code.
What I find most troubling about Myles’ post, however, is the complete denigration of UML. Yes, I’ll admit that I’m a big proponent of UML. There may be a point about UML working really well with the waterfall model of software development, but to then imply that UML is almost completely useless - by association with the inadequacy of the waterfall model to address ‘real’ problems - seems a lot like missing the point of what UML is actually about. Yes, UML may superficially look like ‘architectural drawings or flow diagrams or something’. More importantly, UML is a standard notation to communicate about elements of software design. Beyond the ability of expensive software to create specky, neat and professional looking UML diagrams, UML itself is a tool for software developers to use when thinking about, crafting and communicating about the systems they’re building. By analogy, I would say that an ability to work with UML is like an ability to work with words and sentences and paragraphs. That is probably the reason why IT recruitment agents started using ‘Object Oriented Analysis & Design Skills’ and ‘Sound understanding of UML’ in their job ads - those *are* fundamentally useful skills to have.
As a programmer, I can have a conception of something that is a ‘class’ or an ‘object’ and be able to express the idea in a diagram, say on a whiteboard, while talking with fellow programmers, and still be able to more or less directly translate this concept into code using Java or Python. Using UML, I can model relationships between such classes and talk about such relationships - beyond mere representation, UML can be a valuable tool for solving software design problems, especially in team environments. [And the good news is that there are tools nowadays to automate parts of the translation between UML and code, so you don’t have to ‘go and update hundreds of UML documents every time a minor change was required’] None of this is really dependent upon the specific project management methodology being used. The real problem, as far as IT recruitment is concerned - at least in this region anyway - is that there is often a disconnect between what software development shops need and what their recruitment agents end up publishing. Given that IT recruitment agents are often more experienced in HR and marketing, they end up developing formulas for easily pushing job ads out there seemingly without much consideration for what is really required. That is how you end up with a litany of job ads that look like the same stuff rehashed over and over again. Thanks to all this, graduates who do have such skills end up in jobs which are advertised as requiring their skillset, yet never use them in any useful capacity.
Getting back to the main article, however - the point that DeMarco is trying to make here is rather subtle, one which can best be understood in the very context of his analogy. Developing software, in general, applies to a vast field of human knowledge and applications. As such, decisions about how software should be developed necessarily need to vary based upon the context and constraints within which such development is occurring. By way of analogy, humans, as they grow into adults, cannot be robotically programmed to gracefully handle every possible situation they might encounter. (Or, at least, one could imagine that this approach could fail rather disastrously if tried) Given these limitations, it is far better to learn about core principles and knowing how and when to apply them to produce generally favourable results. DeMarco’s point is that, as this applies to humans, that may be the real way forward for software development.
p.s. Some interesting and relevant articles relating to this topic:
- “Is Software Engineering Engineering?†- Peter J. Denning, Richard D. Riehle
- “Software Engineering ≠Computer Science” - Chuck Connell
You say “I’m a strong believer in the rights of creative artists to control the distribution of their copyrighted content.” Sure, why not? And while we’re at it, we can be strong believers in breathing under water, or living to 130. Those ideas are similar to the idea of controlling distribution, in that there are a whole bunch of people who think they would be really really great. They’re all similar in another way too. Can you guess what it is?
by Tobias Rundström (noreply@blogger.com) at July 16, 2009 04:56 PM
What’s calypso? The new official xmms2 gui client.
I could talk about why the name calypso is a good name, what it means, etc. But I won’t, I’ll write about technical and implementation details.
Based on theefer’s post about extensability and some talks we have, we get to the conclusion that the client should be extensible, based on this I implemented the prototype of a framework to be used during this GSoC and hope that it will be useful in the final client.
The framework is composed of modules, there are two types of modules, I will call them the core and the extension modules. As you have thought the core modules contain core features and serve as the base for the construction of other modules. The core modules are responsible of communication with xmms2 daemon: to control playback, retrieve information, change configuration values, etc. They’re responsible for maintain caches of retrieved data and provide interface to this functionality to other modules. Actually if you look in the code tree you will see three (partially implemented) core modules: playlist, playback and collection.
Let’s talk about the more interesting, extension modules. In this category falls all modules that does not interact directly with the xmms2d daemon or provide basic functionality to the other modules, normally modules in this category have some related UI, for instance, a playlist viewer, collection browser, playback controller, and what else you can think. I’ll post about the ones I implement.
Another difference is related to implementation, core modules are supposed to be implement in some predefined default client language (C++), while extension modules could be implemented not only in the default language but also in some high level extension language (we’ve been trying QtScript).
The current state is the following: there are core modules for controlling playback, playlist and colllection management. In the extension modules field there are a simple playback controller, a playlist viewer, collection browser and the calypso-bar (this one deserves a specific post, but basically, it’s a cli-like controller for all modules).
In terms of Qt naming (I haven’t mentioned but the current prototypes are being developed int python+qt) models classes are normally provided by core modules while the extension modules are viewers and controllers (obviously it’s not a rule, for instance, there can be a lyrics fetcher extension module that’s a model). Related to the UI a module is responsible for providing his own interface (if have one) and there are no restrictions in how it’s created (manually in code, loading an .ui file) it just have to follow some naming rules so it can be used in the main interface.
I think that is it what I wanted to talk in this post, the next ones will be about some specific modules, in the queue there are already the calypso-bar and collection bins.
The tree is in git://git.xmms.se/xmms2/calypso.git you can try it, but be warned for now it’s just prototyping, have lots of bugs and partially implemented things. If you try anyway, please comment.

by Tobias Rundström (noreply@blogger.com) at July 08, 2009 06:39 PM
Hey, this is the first post in this blog, so I’ll describe what’s the blog intentions:
I am working in the XMMS2 official gui client mentored by Sébastien Cevey (theefer). If you don’t know XMMS2 click here, and for cool posts of what an awesome client should be look at theefer’s Star Wars posts.

In 2006 my girlfriend bought herself a MacBook, one of those white ones, pretty, easy to use, and all was well. About two years later the laptop started acting weird. I shut down even though there was still a lot of charge left in the battery and other strange symptoms. A call to Apple and a quick battery check in the store and she got a new battery thanks to the battery exchange program they had running back then, almost no questions asked, and all was well again.
A while ago the battery started acting up again. We came home from a short vacation and the battery icon had a cross over it and the battery didn’t charge. I got on the phone with Apple and they of course answered that I was SOL, but after refusing to accept that they told me to go to an Apple Support store to test if the battery was depleted, or defect. Needless to say it was defect, it had gone from acceptable performance to no performance in the blink of an eye.
Ok, so with the blessing of an Apple technician I called Apple again and now things started to get strange. The support now told me batteries were something you used up and that this battery too was used up even though the technician said otherwise. After a while I had the support guy accept that Apple didn’t manufacture their batteries to suddenly die after a years usage, but rather become less and less able to hold the charge. Based on this acceptance I tried pointing out that Konsumentköplagen (law to protect consumers here in Sweden) protected me from manufactoring errors, and as we both agreed that the battery was incorrectly manufactured, as determined by their party, this would give me the right, and according to me, right to a new battery.
This convincing had taken a while and the support guy was definatly not interested in Konsumentköplagen nor talking with me, so he redirected me up one level after he had explained the case to the next guy.
The next guy had been told by his managers that batteries were something you used up, and thus the Konsumentköplagen didn’t apply, but when asking for a legal reference to his statement that batteries was specifically not covered by the Konsumentköplagen he got a bit defensive, specially after me pointing out that the first hit on Google has the title ”Apple doesn’t care about Konsumentköpslagen”. After a short battle he sent me one step up to something he explained to be their office for more law-related questions.
This time a Danish girl answered and the conversation continued in english and she didn’t seem to have ever heared of the Konsumentköplagen, but was kind enough to give me a 30% discount code on a new battery from Apple Store. I accepted this as the alternative according to her was to talk to their lawyers, and that seemed like a too big effort considering the price of a new battery.
I’m still not completly sure who was right in this case, they never explicitly said that I was wrong. The Konsumentköplagen says that’s it up to the consumer to prove the manufactoring error, but as their technician had determined this already I belive that I was right, and I have still not found any explaination to the relation between Konsumentköplagen and batteries.

by Tobias Rundström (noreply@blogger.com) at May 27, 2009 04:42 PM
So here’s an XMMS2-Scrobbler release that will work with the recently released DrMattDestruction. This new version is witten in C instead of Ruby (so it’s much less memory hungry) and includes support for last.fm’s now-playing notifications.
by Tilman Sauerbeck (tilman@code-monkey.de) at May 10, 2009 12:15 PM
I've been doing some contracting work for 10gen recently. They have that rather cool open source document database called MongoDB and they wanted me to write a module to use that from Perl. I did that and the code is now available on CPAN and github.
Writing that was fun, and I'm already looking forward to be able to use MongoDB as a backend for KiokuDB. I started writing code for that and put it on github, but isn't passing all the tests just yet.
In related news, after finishing the MongoDB module, I'm available for other things again. So if you're looking for a Perl telecommuter, let me know.
by Tobias Rundström (noreply@blogger.com) at May 04, 2009 11:20 PM
Lots of CPAN distributions require some kind of graphical environment. Some of them even pop up windows, which not only very annoying, but also sometimes fails if you're using a tiled window manager.
To test such distributions on a machine where no graphical environment is available or on your desktop while you're working and don't want to get annoyed to death you can use a fake X server, like Xvfb.
The easiest way to do that is to run
$ xvfb-run -a make test
instead of a plain make test. That'll automatically create a fake
xserver, set up DISPLAY and run make test in that environment.
That works well for manually installing modules. When installing using
CPAN.pm you can make things easier by writing a distropref.
First, tell cpan where your distroprefs are. I use ~/.cpan/prefs:
$ cpan cpan[1]> o conf init prefs_dir [...] <prefs_dir> Directory where to store default options/environment/dialogs for building modules that need some customization? [] /home/rafl/.cpan/prefs cpan[3]> o conf commit commit: wrote '/home/rafl/.cpan/CPAN/MyConfig.pm'
Now write a distropref for the modules that need an X server and put
it into your prefs dir as X11.yml
--- match: distribution: | /(?x:Wx |Gtk2 |Gnome2 |... other modules requiring an X server )-\d| test: commandline: "xvfb-run -a make test"
Now the tests for Wx, Gtk2, Gnome2 and all other distributions you list in that regex will be executed with a fake X server.
I have yet to figure out how to write a distropref that just prepends
to the test commandline instead of replacing it so I won't need to
have another pref for all modules using Module::Build.
by Florian Ragwitz (rafl@fsfe.org) at April 29, 2009 03:22 PM
For quite some time perl provided a form of my declarations that
includes a type name, like this:
my Str $x = 'foo';
However, that didn't do anything useful, until Vincent Pit came along
and wrote the excellent
Lexical::Types
module, which allows you to extend the semantics of typed lexicals and
actually make them do something useful. For that, it simply invokes a
callback for every my declaration with a type in the scopes it is
loaded. Within that callback you get the variable that is being
declared as well as the name of the type used in the declaration.
We also have Moose type constraints and the great MooseX::Types module, that allows us to define our own type libraries and import the type constraints into other modules.
Let's glue those modules together. Consider this code:
use MooseX::Types::Moose qw/Int/; use Lexical::Types; my Int $x = 42;
The first problem is that the perl compiler expects a package with the
name of the type used in my to exist. If there's no such package
compilation will fail.
Creating top-level namespaces for all the types we want to use would obviously suck. Luckily the compiler will also try to look for a function with the name of the type in the current scope. If that exists and is inlineable, it will call that function and use the return value as a package name.
In the above code snippet an Int function already exists. We
imported that from MooseX::Types::Moose. Unfortunately it isn't
inlineable. Even if it were, compilation would still fail, because it
would return a Moose::Meta::TypeConstraint instead of a valid
package name.
To fix that, let's rewrite the code to this:
use MooseX::Types::Moose qw/Int/; use MooseX::Lexical::Types qw/Int/; my Int $x = 42;
Let's also write a MooseX::Lexical::Types module that replaces existing imported type exports with something that can be inlined and returns an existing package name based on the type constraint's name.
package MooseX::Lexical::Types; use Class::MOP; use MooseX::Types::Util qw/has_available_type_export/; use namespace::autoclean; sub import { my ($class, @args) = @_; my $caller = caller(); my $meta = Class::MOP::class_of($caller) || Class::MOP::Class->initialize($caller); for my $type_name (@args) { # get the type constraint by introspecting the caller my $type_constraint = has_available_type_export($caller, $type_name); my $package = 'MooseX::Lexical::Types::TYPE::' . $type_constraint->name; Class::MOP::Class->create($package); $meta->add_package_symbol('&'.$type_name => sub () { $package }); } Lexical::Types->import; # enable Lexical::Types for the caller } 1;
With that the example code now compiles. Unfortunately it breaks every
other usecase of MooseX::Types. The export will still need to return a
Moose::Meta::TypeConstraint at run time so this will continue to
work:
has some_attribute => (is => 'ro', isa => Int);
So instead of returning a plain package name from our exported function we will return an object that delegates all method calls to the actual type constraint, but evaluates to our special package name when used as a string:
my $decorator = MooseX::Lexical::Types::TypeDecorator->new($type_constraint); $meta->add_package_symbol('&'.$type_name => sub () { $decorator });
and:
package MooseX::Lexical::Types::TypeDecorator; use Moose; use namespace::autoclean; # MooseX::Types happens to already have a class that doesn't do much # more than delegating to a real type constraint! extends 'MooseX::Types::TypeDecorator'; use overload '""' => sub { 'MooseX::Lexical::Types::TYPE::' . $_[0]->__type_constraint->name }; 1;
Now we're able to use Int as usual and have Lexical::Types invoke
its callback on MooseX::Lexical::Types::TYPE::Int. Within that
callback we will need the real type constraint again, but as it is
invoked as a class method with no good way to pass in additional
arguments, we will need to store the type constraint somewhere. I
choose to simply add a method to the type class we create when
constructing our export. After that, all we need is to implement our
Lexical::Types callback. We will put that in a class all our type
classes will inherit from:
Class::MOP::Class->create( $package => ( superclasses => ['MooseX::Lexical::Types::TypedScalar'], methods => { get_type_constraint => sub { $type_constraint }, }, ), );
The Lexical::Types callback will now need to tie things together by
modifying the declared variable so it will automatically validate
values against the type constraint when being assigned to. There are
several ways of doing this. Using tie on the declared variable
would probable be the easiest thing to do. However, I decided to use
Variable::Magic
(also written by Vincent Pit - did I mention he's awesome?), because
it's mostly invisible at the perl level and also performs rather well
(not that it'd matter, given that validation itself is relatively
slow):
package MooseX::Lexical::Types::TypedScalar; use Carp qw/confess/; use Variable::Magic qw/wizard cast/; use namespace::autoclean; my $wiz = wizard # store the type constraint in the data attached to the magic data => sub { $_[1]->get_type_constraint }, # when assigning to the variable, fail if we can't validate the # new value ($_[0]) against the type constraint ($_[1]) set => sub { if (defined (my $msg = $_[1]->validate(${ $_[0] }))) { confess $msg; } (); }; sub TYPEDSCALAR { # cast $wiz on the variable in $_[1]. pass the type package name # in $_[0] to the wizard's data construction callback. cast $_[1], $wiz, $_[0]; (); } 1;
With this, our example code now works. If someone wants to assign,
say, 'foo' to the variable declared as my Int $x our magic
callback will be invoked, try to validate the value against the type
constraint and fail loudly. WIN!
The code for all this is available github and should also be on CPAN shortly.
You might notice warnings about mismatching prototypes. Those are caused by Class::MOP and fixed in the git version of it, so they'll go away with the next release.
There's still a couple of caveats, but please see the documentation for that.
by Florian Ragwitz (rafl@fsfe.org) at April 28, 2009 06:20 AM
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 page } }
So 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. :-)
by Florian Ragwitz (rafl@fsfe.org) at April 26, 2009 09:14 AM
by Anders Waldenborg (noreply@blogger.com) at April 23, 2009 03:47 AM
by Tobias Rundström (noreply@blogger.com) at April 17, 2009 07:14 PM
by Tobias Rundström (noreply@blogger.com) at April 17, 2009 07:14 PM
I have lately been embroiled in a debate about the importance of commenting in code. While I don’t yet believe that comments are completely unnecessary, I tend to think that they are largely unnecessary. Almost two years ago, I wrote ‘Software development without maps’ in which I extolled the virtues of ‘documentation’. While it can be easy to confuse ‘documentation’ with ‘commenting’ and jump to the conclusion that I’m now contradicting myself, I’d like to draw the distinction between the two. Commenting is only a specific type of documentation - a kind of documentation that is so narrow in scope that it only applies to code. [Sidenote: In general, commenting will end up covering the ‘mechanisms’ expressed by code, and very little of the ‘policies’ and justifications - which would be best covered by higher level documentation anyway.]
In essence, I see programming as an activity where one devises and manipulates abstract models. Writing code is merely a process of expression of such models. What I was trying to get at, in my previous blog post, was that the same models can be viewed at different levels of abstraction. The ‘documents’ encompass knowledge about the models at a higher abstraction level than the code. Documents, being UML diagrams, specifications, or other suitable representations. Comments, on the other hand, are at the same level as code. While it may be useful to sketch out a program using comments before the real code is written, I believe that such ‘scaffolding’ should eventually fade away. Like faint construction lines in a technical drawing, such comments are there to provide an initial framework for laying out the real lines and curves. Like faint and rough sketches on canvas, or a block of stone or wood, the comments become unnecessary as the system is painted, or moulded into shape.
As a software system takes shape and matures, the most reliable indicator of what it is doing is the code itself, not any superfluous comments. Indeed, there are various dangers associated with using and maintaining comments beyond the initial stages of coding:
Looking at the issue from another perspective, what about the usefulness of comments? The machine does not care about comments in the code. Comments do not affect the compiler. Comments do not affect whatever is going to be interpreting the code, or some processed version of the code. That is, indeed, the point of comments. Comments won’t make programs run faster, or in a more stable manner. Comments won’t eliminate bugs. If guns don’t kill people and people kill people, then comments don’t eliminate bugs - people eliminate bugs.
As far as I can tell, the importance of commenting code is 1) seemingly over-emphasised by Computer Science departments, and 2) an unfounded myth perpetuated in programming shops. OK, after a quick trip through IEEEXplore, I found several papers seemingly extolling the virtues of code commenting. However, they all seem to cite the same paper when doing so. A paper written in 1988. A paper about a study based on PL/I and Pascal. Enough said. Clearly, there has been some research done on the topic, but a lot of it seems outdated, especially in the face of more modern concepts such as Object Oriented languages, etc. I shall delve more into this and possibly post a follow-up to this.
In any case, even I was to assume that comments are useful and will bring about world peace, I cannot find any qualitative documentation on the subject. It’s all well and good to say things like “Your code should be 20% commented†or “You need to have comments describing each function†or “Comment about why, not necessarily what, the code is doingâ€, but no one ever seems to have good examples of such. Such vagueness simply serves to exacerbate the problem - anyone can write practically anything they like in comment blocks and get away with it. “Whaddya mean, I wrote comments! See!†A more practical way of posing this question would be: Given that I have a programming task, how do I write good quality comments that will remain useful to future programmers, given what I know about the problem domain, and how I anticipate it to change? Is there an example of this story and how it pans out?
Taking a step back, let’s look at the real problem that commenting pretends to solve.
As I mentioned earlier, programming involves the manipulation of abstract models and expressing them in code. It therefore follows that one gains more by learning how to more effectively express programming code than by decorating code with comments. Programming code is the ultimate middle ground - it is something understandable both by the programmer and by the machine (at some level). The programmer who can write prose in comments does not hold a candle to the programmer who can get the machine to execute exactly what he wants to get done. There are two main reasons for the existence of comments in code: 1) making up for the lack of higher level documentation, and 2) attempting to mask complexity by ‘explaining it in english’.
The first case is symptomatic of a poor development process, where intentions articulated at the business level aren’t properly captured and architected into solutions at various levels of abstraction. In the absence of UML and other such higher level program models, developers are supposed to resort to code comments to explain ‘why’ certain things are being done, even though higher level descriptions would be more accessible to various stakeholders. (This is a variant of the “explain why you’re doing this†style of commenting) Comments used in such a manner simply mask a lack of traceability between what a particular client wants, what possible solutions are presented and approved, and what ends up getting implemented. The valuable historical record of the back-and-forth discussions detailing what happened and when particular decisions were made, is simply lost. Coupled with an environment where developers are added to and removed from a project in a piecemeal fashion, this is simply a recipe for a fragmented disaster, as few of those involved have a complete memory of the sequence of events.
On the other hand, masking complexity by ‘explaining in english’ is plainly disproven by decades of development on programming languages. Concepts such as functions, classes, methods, packages and libraries were developed for the specific purpose of managing complexity by breaking down code into smaller, safer, more tractable and more manageable chunks. Those allow for the implementation of layerable and composable solution patterns, as well as enabling reuse - all techniques well known to help improve the long term reliability and maintainability of software systems. If it weren’t for those, we’d still be writing long epics in FORTRAN.. if we could even get that far.. The fact that classes and methods can be given meaningful names dispels a lot of the reason for using inline comments. Got a function doing lots of things? Break it up into smaller functions that have descriptive names. The code is then easier to follow at a higher abstraction level. Want to zoom in on a specific step? Just go into that function. Easy. Up and down the abstraction ladder.
Despite the various reasons for writing comments, it all boils down to managing complexity: the complexity of stakeholders’ requirements, the complexity of the solution at hand. What I’ve been trying to say is that all of this relates to the management of the development process. By building maps and models of stakeholders’ requirements, a better understanding of the problem domain can be achieved. The process of building such maps and models also helps in the discovery and resolution of conflicting requirements and essential priorities. From there, developers can devise subsystems that - when coupled together - should aim to meet the set of requirements. Such subsystems can then be defined in terms of their interfaces and interactions with each other - all at a higher abstraction level. From there, the team can then zoom in further into each subsystem and attempt to refine the implementation further. This same process can be repeated down to applications, services, packages, classes and methods. The whole ‘stack’ describes the abstraction ladder in a consistent manner, and moving up and down this stack constitutes the ‘zooming’ action. Explaining the process in such a way presents a simple concept that can be applied by various people involved in the process. Stakeholders talk to architects and account managers to produce documents and customer-facing models, while architects present the same documents and models to developers for further refinement and evaluation. The end product of this process is a whole collection of inter-related artifacts that document the history of the project and its various aspects from different perspectives - all of which is much more useful and accessible then comments buried deep in the code.
Another way of looking at the commenting problem is one of situational awareness. Piles of comments (or code, for that matter) are essentially worthless to a programmer until he reads them. (And when he does read them, the code will provide a more accurate picture of what’s happening, rather than the comments) A programmer (A) who writes some code has implicit knowledge of what the code does and why it’s doing what it does. A programmer (B) who simply reads comments written by someone else has explicit knowledge of what the code is doing, but not necessarily any implicit knowledge. A programmer (C) who reads some code written by someone else internalises a more accurate mental model of what the code is doing. Simply put, programmer A devises a mental model and expresses it in code, while programmer C is doing the reverse process by reading the code and building a mental model. While programmer B has some chance of success at building a model, he might end up doing so ‘faster’ than programmer C, but at the expense of an inaccurate - possibly even out of date - model. This whole construction and deconstruction of mental models is exactly why the ‘abstraction ladder’ development process is powerful - it provides models of varying detail at various levels to enable almost anyone to more easily conceptualise any part of the solution and work with it.
by Tobias Rundström (noreply@blogger.com) at April 03, 2009 10:20 PM
by Tobias Rundström (noreply@blogger.com) at March 19, 2009 09:30 AM
by Tobias Rundström (noreply@blogger.com) at March 19, 2009 01:26 AM
by Tobias Rundström (noreply@blogger.com) at March 18, 2009 06:44 PM
by Tobias Rundström (noreply@blogger.com) at March 11, 2009 11:02 AM
by Tobias Rundström (noreply@blogger.com) at March 11, 2009 10:56 AM
by Tobias Rundström (noreply@blogger.com) at March 11, 2009 02:47 AM
by Tobias Rundström (noreply@blogger.com) at February 24, 2009 07:23 PM
I think it’s a great thing for people to finally be stepping up to think of a way forward for XMMS2, especially after a period of relative stagnation. However, I have a few bones to pick with the current shape of things.
Given the direction that the ‘XMMS2 Vision’ is taking, I I’ll say this: I think software freedom is overrated. We’re in 2009, an era where Open Source is practically mainstream - computer manufacturers such as Dell and ASUS are selling desktop and laptop computers with Linux (typically Ubuntu, or some other Debian derivative) pre-installed. ASUS’s Linux-powered eee PC helped launch the netbook revolution, with many observing that the netbook was an ideal application of the low cost benefits of a Linux-based OS. After a decade of people wishing to see Linux as a relatively mainstream desktop OS, it is practically there - any moderately computer literate average Joe can easily grab an Ubuntu Live CD and be on his way.
That’s not to say that freedom is not important, but simply chanting ‘freedom, freedom, freedom’ does not build a thriving community of passionate users. Well, actually, it does, but that’s a kind of community that borders on blind faith, religious dogma and rabid zealotry when it comes to ‘freedom’ - e.g. the cult of GNU. Passionate, indeed, but is this what you see for the future of the XMMS2 project?
When I think about the XMMS2 project, I tend to take the ‘freedom’ aspect for granted, given that XMMS2 has been an open source project for most of its time in existence. It’s a given that XMMS2 is released under an open source licence, and that the small community of loyal developers, users and other fans has been built upon this foundation - I don’t think that is likely to change. When looking for a future vision for the XMMS2 project, I’d say that it would be more useful to search for more practical goals than to get lost in navel gazing about freedom. In the end, what people care about is code that works.
I recognise that putting together this vision is a good opportunity to examine the values that are important to the XMMS2 project. More importantly, however, I think what’s needed is a sharper focus on achieving certain goals. Without a drive towards such goals, we’re pretty much left where we currently are, simply nibbling at ideas that we think are good at the time, without making much progress towards something more coherent.
I’d like to present my own vision for XMMS2 - by no means a definitive attempt, but merely my opinion - and comment on what has been said/written so far.
First of all: XMMS2, what is it? We use the term ‘XMMS2’ in many contexts, with multiple meanings. I feel that, without a clear idea of how to define the term, we’re likely to be left floundering, especially since this is at the very core of what we’re trying to do. XMMS2 is many things:
Personally, over the years I’ve been involved with XMMS2, it has been all this and more:
When I was first introduced to the XMMS2 project, I was merely a university student tinkering with something I found interesting at the time. What I learned from the subsequent experience, however, tremendously increased my development skills and practical knowledge of how software can be developed. I can say with some amount of gratefulness that being involved with the XMMS2 project is one of the major things that has shaped my career as a software developer so far - what I learned from Anders’ engineering skills is still something that has an influence on how I build software today.
Perhaps, then, one might consider ‘education’ as one of the values of the XMMS2 project. Indeed, XMMS2 has been a mentoring organisation in Google’s Summer of Code program for a number of years now - something which I believe has been quite instructive for both the students and the mentors involved. I’d like to think that there are others who might be interested in learning a thing or two about ‘real’ software development to join the community. Granted that code produced by the XMMS2 project is far from perfect, and far from being an academic example of great software engineering, I believe that there is much one can learn by being involved in the community and studying the code. (And no, the XMMS2 project isn’t unique in this respect - many other open source projects also fit the bill)
Beyond what XMMS2 means to each community member, we need to look at where the project is headed. The way I see it, there are two main points to make about this: 1) building the code (or system, or framework - technical excellence), and 2) building the community (community excellence). In this process, we must bear in mind that we’re trying to appeal to certain relatively distinct groups of people:
Both groups view technical and community excellence differently.
In general, as far as users are concerned, if the product works, they’re (mostly) happy. (If they’re really happy, they might even tell their friends) As far as community is concerned, users are happy to occasionally rely on the community for support when things go wrong (Why can’t I play my music, etc). A user’s experience in both respects will dictate how long the user will remain loyal. For example, if XMMS2 can’t easily play a particular file, the user will seek an alternative solution and likely switch to a different player. If the user cannot get the community to resolve a particular problem, or finds the community relatively unfriendly, he will likely gravitate towards a more friendly community.
As far as developers are concerned, technical excellence is about producing interesting code in particular ways - a more efficient algorithm, a more flexible plugin system, a library with a clean API, a seriously cool feature that’s not available anywhere else. The cornerstone, however, is the existing developer community around the project - these existing developers are the gatekeepers to the existing codebase, the ones with inside-out knowledge of how the existing system works, the ones who share the history of the project and dictate where it is going. The interface between contributing developers and core developers is exactly where the value of ‘open source’ comes into play. On one hand, contributing developers are attracted by how easy it is for them to modify existing code to introduce new features or fix defects, and on the other hand, core developers must have processes in place to ensure that code of relatively high quality is accepted - while encouraging the better contributors to remain interested.
Somewhere in the middle, there’s an intersection between the set of users and the set of developers. This typically takes the form of passionate users with certain skills moving towards becoming developers by contributing code to the project. In general, I think that this should be encouraged, as it grows the base of community members available to support users and induct new developers.
OK, so I’ve talked a bit about what I think is important for XMMS2 as a community. I’ll post some more later about users, developers and XMMS2 as the product.
by Tobias Rundström (noreply@blogger.com) at February 15, 2009 10:38 PM
by Tobias Rundström (noreply@blogger.com) at February 15, 2009 10:28 PM
Installed the Last.FM player on my Android yesterday and I suddenly knew that I had just taken a leap into the future.
The days of myPod’s and other digital music players are reaching their end. I realise that while writing this, millions of people sit in front of their computers pushing music into their little gadgets before heading out in the street or whatever, and you know what…
<blink>THEY’RE DOING IT WRONG!</blink>
What they should do is to get themselves an Android or iPhone, install the Last.FM app, just head outside and click the ”xxxx’s Library” station and enjoy song after song they probably just want to hear right now, for free! The whole world of music instantly available from that Internet enabled device in their pocket.
<blink>THIS IS THE FUTURE! IT’S HERE!</blink>
It’s has also revolutionized my use of Last.FM. As I’m using it on the go I’m not really doing anything other than listening to music so it brings me closer to the music in a whole new way.
If I hear a song it’s really easy to just pick up the phone from my pocket and press the <3 button, maybe skip to the next song if the current one doesn’t fit my mood, or if the song reminds me of someone, the share button is just a click away, both share to email from the android contacts list, or to my friends at Last.FM.
I haven’t been this excited about a piece of software since I first started using Xbox Media Center, this IS the best thing since sliced bread (or XBMC in this case).


by Tobias Rundström (noreply@blogger.com) at February 09, 2009 12:03 PM

by Tobias Rundström (noreply@blogger.com) at February 08, 2009 12:48 PM


by Tobias Rundström (noreply@blogger.com) at February 02, 2009 08:32 AM
Antes de comenzar a programar un cliente para el xmms2 tendremos que investigar como funciona, como es que logra comunicarse con un o muchos clientes al mismo tiempo.
Para interactuar con el servicio xmms2d es necesario hacerlo por medio de un intermediario (middleware) que llevara la comunicación entre el servidor y el cliente.
Es decir, el demonio xmms2d se ejecuta a la espera de peticiones, mismas que le serán pedidas por el intermediario; en la imagen superior vemos a dos objetos de tipo libxmmsipc quienes son los que están enlazados y pueden comunicarse en el mismo lenguaje, empero, el de la izquierda se entiende con el demonio, y el de la derecha con el cliente. A estos dos en conjunto les llamamos Middleware.
Afortunadamente existe una libreria en python que ayudara a actuar como intermediario entre el demonio y nuestro cliente. Esta libreria es llamada python-xmmsclient.
Los desarrolladores de xmms2 nos proponen algunas reglas de deberemos seguir para tener un buen funcionamiento entre nuestro cliente y el servidor, y no afectemos configuraciones que todos los clientes utilizan.
Entre ellas, respetar la variable de entorno XMMS_PATH, o si nuestro cliente guarda configuraciones podremos hacerlo dentro del directorio apuntado por $XDG_CONFIG_HOME. Así como algunas otras mas (para mas información aquí).
Los desarrolladores nos han facilitado tanto el trabajo que disponemos de Medialib, que es una función que parsea la información Tag de un archivo de audio, poniéndola en una tabla que fácilmente podremos manipular.
Existen dos modos de comunicaciones básicamente, un modo síncrono y uno asíncrono, cada uno con su respectiva función para determinados casos. Vamos, que si desarrollamos un cliente en modo texto plano para consola, podremos usar un modo síncrono sin ningún problema, pero si nuestra aplicación será algo mas sofisticado y gráfico, lo mas recomendable es usar una comunicación asíncrona.
¿Por que asíncrona? Bien, para que me puedas entender mejor voy a tratar de explicar algunas funciones que se llevan a cabo en la comunicación cliente-servidor.
Pongámoslo fácil, cuando nosotros ponemos play, estamos ejecutando un comando, y este comando envía una señal al demonio que interpreta y regresa un resultado, mismo que el cliente puede interpretar a como le de la gana. Pero, supongamos que abrimos 2 clientes, ambos saben que existe una lista de reproducción cargada, en el primer cliente se nos ocurre borrar esta lista, entonces el segundo seguirá teniendo la lista completa sin sufrir ningún efecto y esto podría causarle problemas, por lo tanto, este debía ser avisado (por medio de una emisión del demonio) del cambio y tener la misma información que el primero, por ello que la comunicación debería ser asíncrona.
Por ahora todo ha ido perfecto, en los próximos post’s tratare de mostrarles como hacer una conexión con un sencillo script en python.
Enlaces:
En el post anterior hable de este misterioso reproductor de audio para sistemas operativos de tipo unix, y debido a la falta de interfaces gráficas (Clientes) que satisfagan mis necesidades como usuario he decidido programarme uno.
El lenguaje que elegí eventualmente es python usando la librería wx; ya que quiero probar mi suerte en diseños de GUI y ver que tan adaptables pueden ser.
Bien, algunas características que quiero implementar.
Por el momento he diseñado una interfaz que me agrada (un poco parecida a esperanza), aunque probablemente pueda cambiar en algún momento y quiero usar mi blog para dar a conocer el seguimiento que le estoy dando.
Afortunadamente existe una librería para python (python-xmmsclient) que me facilitará el trabajo, pero de ello hablare un poco después. Aquí muestro el interfaz que he diseñado.
El proyecto llevará por nombre Angel, aunque no es el definitivo, y el motivo, bueno, este si es personal. Y si alguién se anima a contribuir al proyecto hagamelo saber, toda ayuda es bienvenida.
by Tobias Rundström (noreply@blogger.com) at January 04, 2009 10:38 PM





by Tobias Rundström (noreply@blogger.com) at December 22, 2008 09:46 PM
by Tobias Rundström (noreply@blogger.com) at December 16, 2008 06:05 PM





by Tobias Rundström (noreply@blogger.com) at December 11, 2008 07:39 PM
by puzzles (noreply@blogger.com) at August 19, 2008 02:15 PM
service_t:
char *name;
char *desc;
uint32_t major;
uint32_t minor;
x_list_t *methods;
uint32_t ref;
service_method_t
char *name;
char *desc;
void *udata;
xmmsc_service_notifier_t func;
xmmsc_user_data_free_func_t ufree;
xmms_value_type_t rettype;
xmms_value_t *args;
void llamagui_llama_count_get (connection_t *xc)
{
value_t *farms = list_new("llama_farm_a", "llama_farm_b");
value_t *args = dict_new("farmlist", farms);
res = service_query(xc, "LlamaCount", "count_get", args);
service_notifier_set(xc, res, llamagui_llama_count_callback);
}
value_t *llamacount_get (connection_t *xc, service_method_t *method, value_t *args, void *udata)
{
int count = 0;
value_t *farmlist;
farmlist = value_dict_get (args, "farmlist");
for(; value_list_valid(farmlist); value_list_next(farmlist)) {
count += llama_farm_count (value_int_get (farmlist));
}
return value_new_int(count);
}
void llamagui_llama_count_callback (value_t *ret)
{
if (value_type(ret) == VALUE_TYPE_ERROR) {
llamagui_error_set("Oh no! A llamacaust occurred. Error %s", value_error_get(ret));
return;
}
llamagui_llama_count_set(value_int_get(ret));
}
by Anders Waldenborg (noreply@blogger.com) at June 15, 2008 11:49 AM
It's that time again. People are walking around in flip-flops, getting tan(ner), and licking ice cream from cones. It's summer (or it's close enough, anyway), and this summer I'll be getting my tan from the computer monitor and my ice cream from the freezer. It'll be a basement-dweller's summer for me as I'm coding on XMMS2 in this year's Google Summer of Code.
I'll be working on service clients, a continuation of last year's unmerged work. The concept is to provide so-called "service" clients which perform a service (surprise!) that can be re-used by other clients so client authors aren't reinventing wheels all the time. It's just another way XMMS2 eases music player development to the point where making your own interface is a weekend project instead of a thesis project.
The client-server nature of XMMS2 is a constant issue when trying to add new features or fix bugs. What was trivial to accomplish in a monolithic music player is not so trivial in XMMS2, and vice-versa. Service clients are a way to provide the same whipped-cream-and-cherry features you'd find in a monolithic client, but in a reusable, modular, and extensible form. It's cleaner than adding new stuff straight to the daemon, but still fairly simple and straightforward to use.
Service clients work by registering themselves and their callable methods with the XMMS2 daemon. Regular clients (or even service clients, as they're regular clients, too) request a service client from the daemon and call its methods appropriately and get back data. It's that simple. Album art lookup, tag lookup, last.fm submissions, and FreeDB lookup are all easily written as service clients and their functionality is very easily included in any client by use of a few methods. Services are even browseable so, with a little user intervention, a new service client could be used from a client that has no idea how to use the service, at least in theory.
Service clients were part of last year's Summer of Code program, completed by student Ning "zeegeek" Shi under the direction of mentor Sébastien "theefer" Cevey. The API works and there are a couple service clients floating around, but zeegeek's codebase was never merged with the main XMMS2 tree. The code needs a full review and some questions about remaining oddities answered. A little bitrot has accumulated since last summer, too. My job will be to clean up the code and get it merged, first.
Later I'll also be writing the first language bindings in Ruby. This, too will be followed by a merge. Too often, Summer of Code projects are completed but remain unmerged for months, creating lots of work later. This summer, I'm including merges as part of the project goals. Once the service client API and Ruby bindings are completed and merged, it's time to take service clients' virginity. It won't be just a framework anymore, but I'll implement some useful clients, starting with a port of xmms2-scrobbler. And of course, this'll be followed by a merge as well.
Then more cool clients will follow. The next generation of collections, (Collections 2.0) also being implemented this summer, will probably implement the collections parser and a more flexible party shuffle as service clients. This is an exciting collaboration opportunity. Other possibilities include a medialib-updater styled service, taglib client, FreeDB/musicbrainz lookup, and album art lookup. I'm outlining way more service clients than I can handle this summer in the hopes that I can pick out an important and doable few and get those few done and merged by the end of SoC. They'll also be indispensable means of clearing up remaining kinks and bugs in the code while establishing some good example code and helping me write documentation.
Working on service clients this summer is exciting and I'm overjoyed that this is my first SoC. This is an excellent project with an excellent team during an excellent summer, so I've little doubt that all this year's projects will be successful. I'm hyped, and you should be, too! Stay tuned for when I finally settle down with a six-pack and start exercising my fingers.
by Anders Waldenborg (noreply@blogger.com) at April 22, 2008 12:48 AM