Saturday, December 10, 2011

A kind of call by name

I often write code like this:
$self->create_user( username => $username, email => $email, pass_token => $pass_token );
I wish I could get rid of the naming redundancy in this call:
$self->create_user( $username, $email, $pass_token );
(without changing 'create_user' of course).

Probably some new syntax would be needed.

Friday, November 18, 2011

'use strict' and cargo cult programming

I've just read  mjd's confession "Why I Hate strict", it is from 2003 so he might have changed his views now, but there is nothing that would indicate that on this web page.  Anyway, his main argument that the usual advice to use strict is automatic and mindless  and that it often does not really prevent the problems that people think it does.  In other words it is a cargo cult programming to which he contrast programming with thinking and deep analysis of everything you do.

I used to program without use strict; use warnings but after exposure to the usual propaganda I switched and I found that the cost of mindlessly adding it is negligible, the cases where I need no strict are very rare, and there are many benefits of doing it, especially when working with old code.  This cult is rather effective in luring the cargo planes to land in my atoll.  On the other hand I am all for deep analysis and checking your assumptions from time to time.  There are many valid points in Marc Lehman common::sense and I would like to see them discussed.  While we are on the road to have use strict by default we might also try to make it better.

Saturday, November 12, 2011

$ primes for money

The thesis above sounds uncontroversial.  It is also rather uncontroversial that '$' is relatively frequently used when programming in Perl.  Now - what can be the consequences of that?
Money has been said to change people's motivation (mainly for the better) and their behavior toward others (mainly for the worse). The results of nine experiments suggest that money brings about a self-sufficient orientation in which people prefer to be free of dependency and dependents. Reminders of money, relative to nonmoney reminders, led to reduced requests for help and reduced helpfulness toward others. Relative to participants primed with neutral concepts, participants primed with money preferred to play alone, work alone, and put more physical distance between themselves and a new acquaintance.
from one of the first links in the query above.  Pretty sad - can that apply to the Perl community? Another link from that list, an entertaining BBC video report suggests also some other effects: hunger and pain insensitivity.

Monday, November 07, 2011

Thesis: simple - antythesis: easy - synthesis: ...

Rich Hickey's Simple Made Easy is a great talk, a must see, with lot's of insight, but together with that it also misrepresents what Agile is about.  Hickey's main point is that we should try to write simple software, because this is the only way to have reliable software, and he is right of course.   He notes that when you encounter a new bug and try to fix it - all the existing tests pass - so they will not help you in finding the cause of it.  You need to do the bug analysis on your own  and the complexity of your code is your enemy there.  He is also right when he talks about how easy means familiar a not simple and that it is a trap because it drives us away from the other (in small increments I would add).  He is insightful when he talks about things that are source of complexity.   He is funny, but missing the point in his critique of Agile.

The development sprints he attacks are not about doing the bulk of the work - they are about building a prototype on which we can test our assumptions.  Without the understanding that we get from these prototypes we could simplify as much as we want but it would not change the fact that our solution solves the wrong problem.  Agile is not an enemy of simple, it puts a lot of weight to doing the easy - but not because this is the goal - rather it uses easy as a mean to get to the correct. Agile is the answer to the paradox that we don't know what we should make until we already have a prototype of that thing.  I wish more developers cared about simple - but only after they know what is needed.

Tuesday, November 01, 2011

Notes on the Synthesis of Form

According to Wikipedia the origin of  Design Patterns lays in the Pattern Language ideas by the unorthodox architect and philosopher Christopher Alexander, but his earlier work also used to be widely read by computer scientists:
Alexander's Notes on the Synthesis of Form was required reading for researchers in computer science throughout the 1960s. It had an influence[8] in the 1960s and 1970s on programming language design, modular programming, object-oriented programming, software engineering and other design methodologies. Alexander's mathematical concepts and orientation were similar to Edsger Dijkstra's influential A Discipline of Programming.
The solution to the design problem that he proposes there does not look too attractive now, but his models, his metaphors, his insight into the design process - it's all still relevant and spot on.  I am surprised that the Agile movement does not quote "Notes" as one of their foundation texts.

Saturday, October 15, 2011

Concentration and Flow or Yet Another Dependency Injection Note

Imagine that you need to do some small home improvement or maintenance work and you have all the needed tools, in good quality, clean and well maintained with all cutting blades sharpened and no missing screwdriver heads. A nice feeling - isn't it? When you start work like this you can concentrate on the task at hand instead of thinking where you can borrow that drill tool.

Collaborators in an algorithm are like those tools, having them readily available lets you concentrate on the problem.

Friday, October 14, 2011

Object oriented versus functional interface

I use DateTime::Format::W3CDTF for parsing my dates:

my $w3c = DateTime::Format::W3CDTF->new;
my $dt = $w3c->parse_datetime( $date_string );

I wish it was:

my $dt = DateTime::Format::W3CDTF->parse_datetime( $date_string );

and that the library created the parser on the fly as needed. It's not only less typing - but also much simpler mental model. This simpler model is sometimes too simple - for example if you parse a lot of dates then sparing the parser creation each time can make a difference.

I think the optimal thing to do is provide two APIs - like JSON - a functional one:

$perl_hash_or_arrayref = decode_json $utf8_encoded_json_text;

and an object oriented one:

$json = JSON->new->allow_nonref;
$perl_scalar = $json->decode( $json_text );

for those that need that extra control.

Monday, October 03, 2011

open expects filename as binary data encoded in the system characterset

I guess this is not a surprise to anyone who thought about how this is supposed to work, but for the sake of being systematic, here is the code:
use strict;
use warnings;
use autodie;
use HTML::Entities;
use Encode;

my $a = HTML::Entities::decode( 'ñ' );

open(my $fh, '>', $a );
print $fh "Without encoding\n";
close $fh;

open(my $fh1, '>', encode( 'UTF-8', $a ) );
print $fh1 "With encoding\n";
close $fh1

And here is the result when run on an system with UTF8 locales:
zby@zby:~/myopera/tmp$ ls
? a.pl ñ
zby@zby:~/myopera/tmp$ cat ñ
With encoding

'a.pl' is the name of the script itself, the mark '?' hides the F1 hexadecimal code and that file contains 'Without encoding'.

Friday, September 30, 2011

Courriel::MMS

I think it is time to announce Courriel::MMS - it is an extension for the new email handling library by Dave Rolsky for processing MMS messages forwarded as emails by the mobile operators. This is still just a github link, no CPAN package yet, but it works in our production servers since Wednesday - so I bet on this code :)

It is a bit heuristic - for example many operators send a subject like 'You have received an mms' - which is useless for us, so the library tries to find something else that would act as the subject we need. For dealing with the various mobile operators, that each send a slightly different format of these emails, I used the Factory design pattern together with Module::Pluggable - this is a novel design for me so I wait for comments.

Tuesday, September 20, 2011

URI->path expects binary data

Update: changed new to path - with new it would be reasonable to require that the uri fed to the parser is already an ASCI string containing the already URI encoded url.
Consider this code:
use 5.010;
use Encode 'encode';
use URI;

my $uri = URI->new( 'http://example.com/' );
say $uri->path( encode("UTF-8", "can\x{00B4}t-make-it-work" ) );
say $uri->path( "can\x{00B4}t-make-it-work" );

The output (in perl 5.14.0) is:
http://example.com/can%C2%B4t-make-it-work
http://example.com/can%B4t-make-it-work

If your page is encoded in UTF8 - then the first one is correct: %C2%B4 is the URI encoded UTF8 encoding of Unicode Character 'ACUTE ACCENT' (U+00B4). If your page encoding is Latin1 - then the second one would be correct - but this is only by accident - in that case you should still use encode("iso-8859-1", ...).

There are probably many other string manipulating libs that should document if their input should be binary encoded data or decoded character strings.

Thursday, September 01, 2011

Names are special

At perl.com Tom Christiansen talks about sorting names, among other things. It appears surprisingly difficult to do properly with many special rules for each language. By coincidence at programming.reddit.com just above a link to that article there is Personal names around the world - a link to a w3c article about even more complications with names. At PhilPapers we had to solve *somehow* a few of these - the result is Text::Names. It is still rather limited: "While it tries to accommodate non-Western names, this module definitely works better with Western names, especially English-style names" - but there is already lots of logic embedded there.

Sunday, August 28, 2011

is_utf8 is useless - can we have is_character?

Consider this code:

$data_structure = utf8::is_utf8($json)
? from_json($json)
: decode_json($json);

taken, together with the is_character suggestion, from otherwise very informative post: Quick note on using module JSON. I have seen similar code in many places. The idea is to check if the string you have is character data or a string of bytes and treat it appropriately. Unfortunately is_utf8 does not do that check:

use strict;
use warnings;

use utf8;
use HTML::Entities;
use JSON;

my $a = HTML::Entities::decode( ' ' );
my $json = qq{{ "a": "$a" }};
print 'is_utf8: ' . ( utf8::is_utf8( $json ) ? 'yes' : 'no' ) . "\n";

my $data_structure = utf8::is_utf8( $json )
? from_json( $json )
: decode_json( $json );


This fails (on my machine) with following output:

is_utf8: no
malformed UTF-8 character in JSON string, at character offset 8 (before "\x{8a0}" }") at a.pl line 12.

If that still is a mystery try this:

use strict;
use warnings;

use HTML::Entities;
use Devel::Peek;

Dump( HTML::Entities::decode( ' ' ) );

the output (on my machine) is:

SV = PV(0x24f2090) at 0x24f3de8
REFCNT = 1
FLAGS = (TEMP,POK,pPOK)
PV = 0x2501620 "\240"\0
CUR = 1
LEN = 16

this string is internally encoded as "\240" i.e. "\x{0a}" which is Latin1 encoding of non-breaking space. It does not have the utf8 flag set - so the code above tries to treat it as UTF8 encoded stream of bytes and fails.

I don't know if we can have is_character easily - but the lack of introspection here is surely painful.

Wednesday, August 24, 2011

CPAN, decoupling and Dependency Injection

Consider the code:

sub fetch
{
my ($self, $uri) = @_;
my $ua = LWP::UserAgent->new;
my $resp = $ua->get( $uri );

...
}


Yes - this is taken from a post by chromatic.

Now imagine that this is code from a CPAN module you installed and that some security concerns require you to replace LWP::UserAgent with LWPx::ParanoidAgent there. Bad luck - you'll probably need to subclass it, override that whole fetch method and pray that it will not change too much with every new release of the original module.

This is really why I am drumming this Dependency Injection drum over and over again - code that uses it is more reusable, more universal:

use Moose;
has 'ua', is => 'ro', default => sub { LWP::UserAgent->new };

sub fetch
{
my ($self, $uri) = @_;
my $ua = $self->ua;
my $resp = $ua->get( $uri );

...
}


Now you would not have any problem with providing a LWPx::ParanoidAgent object for the fetch method to use.

By the way, with classical DI you'd move that LWP::UserAgent->new completely out from the class, here it stays as a 'default' that can be overridden from outside if you need. The problem with classical DI is that you need to have a place where to move that initialization code - here it is sidestepped for the 'normal' usage and you need to worry about it only in the cases where you really need to. Java probably does not have this 'default' mechanism.

Thursday, August 18, 2011

Dependency Injeciton - the cooking metaphor

Let's take a typical recipe. It first describes the goal - and then it goes:

Ingredients:

  • 2-1/4 cups sifted cake flour
  • 2 teaspoons baking powder
  • 1/2 teaspoon salt
  • 1/2 pound (2 sticks) sweet butter, room temperature
    ...

Preparation:
Preheat the oven to 350 degrees Fahrenheit. Butter and line two 8 x 3-inch baking pans or one 12 x 3-inch pan with parchment.


It is not:

Preheat the oven to 350 degrees Fahrenheit. Find a cow and milk her, wait until ...

neither it is:

Preheat the oven to 350 degrees Fahrenheit. Take your credit card and go to the grocery around the corner ...


Dependency injection is about writing your programs in a very similar manner - you first declare the collaborators and then go on with using them.

Thursday, August 11, 2011

So what is Dependency Injection again?

The definition I like the most is that DI is simply about separating object creation from business logic. Object creation - wiring the application - is a special type of code, different from the rest and it is useful to keep it separated. This is similar to how we remove hardcoded magic constants from our code into config files, it can be thought as a Object Oriented extension of that practice. We remove magic constants because we need to change them more frequently than the rest of the code. We do DI because we need to change the object wiring much more frequently than we change business logic and in particular we need to change it in the tests - without that unit tests would not be possible. But it is also different - because the object wiring code is much more complex than configuration files.

But this is not all - DI is also about keeping all object collaborators in it's attributes instead of reaching out for global objects (or signletons which are globals in disguise or class attributes). It thus improves object's encapsulation, makes them more self-reliant and testable. Or maybe this part is not DI - but simply writing Object Oriented code?

On the other hand, the separated out object factories are hard to test because they depend on all the objects classes they create and you want to keep them as small and simple as possible. How many such factories you need? If we have something that has a http request object as attribute - then we cannot build it until the http request arrives from the user. If we keep all collaborators in objects attributes - then we cannot build them until we have all information needed to build all these collaborators first. We thus need one factory per scope.

Tuesday, August 02, 2011

Subclassing applications

Subclassing is a great tool for making small changes to a piece of code to fit it to new requirements. It is as easy as copying code - but it still keeps the new constructs synchronized with later changes to the original. There are problems with inheritance hierarchies - but you need to have a 'hierarchy', not just two classes, to get there.


I imagine that it would be perfect for extended configuration of applications - including web applications. Wouldn't it be great if you could run a slightly changed version of you main web app by making it's code available from PERL5LIB and then subclassing it to change the colors used, add some minor new features and remove some pages for and affiliated site? Or if you could install a blog engine from CPAN, and then subclass it to add new and override old features? This could even make distribution of CPANized applications more popular.

This is one of the things I am experimenting with at Nblog (see also the screencast: Experiments with inheritance in WebNano based applications).

Monday, June 27, 2011

Callbacks versus the Template Method pattern

Let's say you have an object oriented html form validation library and, beside all the default checks (like non-empty or is_number etc.), you want the users of your library to add their own checks coded in the native programming language of your library. You have two simple ways to do that - you can let the form object contain a callback to be used for the check or you can use the Template Method pattern and let programmers subclass your form (or maybe individual field) class and implement their own 'check' method. Both solutions have their own pros and cons but I've never seen a comprehensive comparison of them.

What do you think about them? It seems that some programmers groups prefer one solution over the other (it's hard not to notice how callbacks are popular in the Plack related stuff). Callbacks are simpler, you don't need additional classes there, they don't complicate the program structure, but they are also more constrained. Template Methods are more structural. You can make them call other template methods and make that whole thing fine grained - that is harder with callbacks. In FormHandler I wanted to be able to stack the many generic checks together into lists - but such lists are not very reusable, you cannot override parts of it like you could if they were named methods. The point is that this additional class is another indirection layer and as we know that all programming problems are solvable with in this way :)

Saturday, May 28, 2011

The Bitcoin protocol - a highlevel explanation

Bitcoin is a peer to peer financial protocol. There is no central authority that guarantees that the operations are valid, how can this work? How can you trust strangers with your money? Let's say you are selling something for bitcoins - you receive the amount quoted - how can you verify that the transaction was valid? You need to check three things:

  1. That it was indeed the owner of the sender account that created the transaction.
  2. That the acount has the BTCs that are now being sent - i.e. that it previously received them.
  3. That he has not transfered these BTCs already somewhere else (double spending).

The first check is easy - all transactions are signed. For the second you need to know another transaction that transfers the money to the senders account. Of course now you'll need to verify the other transaction as well - and then, in a recursive fashion, all the others leading to the one that generated the bitcoins (more about generating later). The sender could send you this chain of signed transactions - but in fact he does not need to do that because all the transactions are public.

The third check is more tricky - for this you need to always know which transaction was first and which one is second and then possibly reject the second one if it is double spending. This would be easy with a central authority that would timestamp all transactions and log them somehow - but it is very hard to do in a p2p system. In bitcoin there is also a global log of all transactions - it is called block chain (for it's technical representation). The trick is that to add a valid record to that log you need to solve a hard computational problem. You practically have no chances to do that singlehandedly and you need the other nodes in the network to help you. The sender broadcast his will to transfer money to the whole network and then wait until someone from this network solves the problem and correctly saves the transaction to the global log. This is like going to the notary to make sure that all formalities are met. After the transaction is saved to the log it is very hard to undo that - because you'd need to solve this hard problem again - and without a conspiracy between a significant part of the peers this would be impossible.

To be more precise transactions are not logged individually - but rather in batches called blocks. Such a set of transactions is written to the log in one sweep. This is important for efficiency - but not only.

All of this happens in a distributed, asynchronous manner. This means that it is possible that two nodes will write two new blocks to the transaction log in parallel and we'll get two different and valid versions of the log. What would happen then is that when a next block is written down to one version of the log it will take over all of the transactions from the block in the alternative log version, so they are not lost. But it is possible that the alternative logs contain two conflicting transactions (double spending) - then only one of them will be eventually saved. This showcases one important thing - having the transaction written to the log does not yet guarantee that it will stay there, because it can happen that there exists an alternative, valid log version and that eventually this other one will be the one that is continued by the system. But if you wait until another block is written to the log after the one that you are checking - then you are much more safe. This is the most complex part of the protocol - but the general rule is that the more blocks are written to the log after your - the more safe you are, and the safety grows exponentially.

Now - why so many nodes in the network would spend their time trying to save a new transaction block to the log? This is because they are paid if they succeed. In each new block saved to the log there can be one transaction that generates a specific amount of BTCs (now it is 50 - but it will be less in the future). This is they way new bitcoins are generated.

Another question is how the bitcoin project can maintain that the transactions are anonymous when they are all public? The answer is that what is public is the addresses of the sender and the receiver but not who owns these addresses. It is easy to create new addresses. You can use a new one for every incoming transaction and you can also make transfers between your own accounts to hide the tracks. Maybe it is not total privacy - but it is still better then with current money transfers where the banks know everything.

This introduction leaves out lots of technical details - but I hope that it explains the protocol enough to convince readers that it can work :) For more details have a look at the original bitcoin paper and the bitcoin wiki (just remember that what I call transaction log here is called block chain there).

By the way - I've heard bitcoin makes internet tipping in fashion again - so 113uhu2LrJp8gXGDrDLLDqmFGxnC2e3suB is one of my addresses. The interesting twist to that is that the donations are public - you can view the current ballance at blockexplorer. I've already got some tips - thanks :) Consider this an experiment in micropayments for blog financing.

Update: A critical analysis of the decentralization of the bitcoin protocol: http://www.links.org/?p=1164

Sunday, May 15, 2011

Synthetic attributes

chromatic writes about synthetic attributes. I wonder why this is not more widely used - it's such a simple technique. I've been using it since I discovered Moose and all the time in the back of my head I had this thought: Why people don't use this more widely? It is so obvious solution to the testing problems. Maybe they know something that I don't? But maybe it is just the matter of some guru (like chromatic :) writing about this technique?

PS. Sorry I'll not explain what synthetic attributes mean - this post is only a comment. I cannot currently comment at chromatic's blog.

Tuesday, April 12, 2011

git push and other copy commands

The usual pattern of a copy command:

copy source destination

The pattern of git push command

push destination source:destination

the first destination is the destination repository - the second is the branch (and 'source' is the source branch). I must have skimmed the linked manual dozens of times over many years. There was something that just did not make sense and I imagined that I would have to read some book or something to eventually understand the magic 'ref specs'. It never dawned on me that it was that simple.

The additional difficulty is that the destination repository is usually shortened to 'origin' (because it was the origin for the clone command).

Saturday, March 26, 2011

Drupal like architecture

The Drupal subject reappears in the Perl blogsphere regularly. In my opinion there are three key architectural choices for 'portable plugin apps'. First, obviously, the plugins needs to be highly independent. Second they need to be controlled by pages - that is the page decide what plugins to use. To meet the independence requirement, in the Plack world, the obvious choice for the plugis is that they are simply PSGI apps that in body return a page fragment. This will make it easy to plugin existing wikis and blogs - you just need to remove the header and footer templates and voila you have a plugin instead of a standalone app. You can also use all the Plack infrastructure, for example the Plack::Client if you ever care about scaling your application.

There is one thing that I forgot in the first version of this post - Javascript and CSS. Applications are rarely pure HTML these days - we'll need also some way to gather all the js and css files that the plugins use and link them in the main page. At the main page side this is nothing special - it is not unusual that applications concatenate many Javascript libraries into one file automatically - so this is already well explored. The complication arises from the requirement to pass something more structured then just a HTML fragment in the Plack response from the plugins.

More interesting is the other key choice - how the plugins are supposed to be plugged in. That is how page handlers will choose what plugin to use and what data pass there. As much as I hate the 'program in XML' approach to language syntax - the obvious established standard here is ESI. Maybe we could even steal the semantics and replace the syntax with something saner? Plack based ESI implementation was submitted as an example GSOC idea - I really hope some student will pick it up.

Update: Added js/css handling consideration (thanks for cezio comment below).

Saturday, March 19, 2011

App initialization and web frameworks

Building the application object and its components has nothing to do with serving web pages. The database model setup is exactly the same if you do it for a web application or for your cron utilities and it should also remain the same if you one day decide to make a desktop version of your app. There is no reason that this initialization is a part of web frameworks other then we don't currently have a good standalone application builders. Now every web framework reinvents the wheel and writes one from scratch. Fortunately (in the Perl universe) there are now multiple efforts to create the ultimate configuration engine. There is just one step from a config reader to an application configurator.

As I have already commented elsewhere, I think the ideal for big projects would be a simple config file using simplified syntax that could be changed by the admins plus a Dependency Injection container that would build all the application components from the primitive values provided by this config. This DI container would be a second level configuration - still simple code but touchable only by programmers. For small applications I was quite happy with MooseX::SimpleConfig and Moose type coercions.

Tuesday, March 15, 2011

Reblessing objects

Yesterday I've read the example from Refactoring transcripted into Perl. Nice work (I am not sure about the legal status of this - but I am sure that it is a great advert for the original book). The last refactoring there starts with:

We have several types of movie that have different ways of answering the same question. This sounds like a job for subclasses. We can have three subclasses of movie, each of which can have its own version of charge (Figure 1.14).

This allows me to replace the switch statement by using polymorphism. Sadly it has one slight flaw - it doesn't work. A movie can change its classification during its lifetime. An object cannot change its class during its lifetime.


It then goes on to show how the State Pattern can solve the problem thus stated. I am not so sure about this argumentation - typically the movie data would be stored in a database and the object would be created just for the one transaction - I think it is reasonable to assume that the movie does not change it's classification during the transaction. But OK - all this is just to show how the State Pattern solves the problem even if in this case the problem itself would not be real - for sure there are cases where it would.

Then it got me thinking - well in Perl you can change the class of an object during it's lifetime. I've even seen it done, I don't quite remember where. In general it is considered to be nasty - but is it always? In real life it is normal that things change - a caterpillar becomes a butterfly, a child becomes an adult.

Monday, March 14, 2011

Spark::Form

I remember when when James was starting his project - his basic ideas were exactly the same as our HTML::FormHandler design. Unfortunately he learned about FormHandler after he had started coding - no way to talk him to change his plans and join FormHandler. Reinventing the wheel - but what I can decipher from his latest presentation - is quite interesting. Model integration - which is a major source of the complexity he criticized in HFH - is still lacking but the validation method is intriguing. Maybe cross-pollination will be possible?

Tuesday, March 01, 2011

Plack::Middleware::Auth::Form on CPAN

I've got a bit impatient in waiting for feedback and this week I uploaded Plack::Middleware::Auth::Form to CPAN. This does not mean it is entirely finished - but at least it should be easier to install.

Plack::Middleware::Auth::Form has similar functionality as CatalystX::SimpleLogin, but since it is at the Plack level it can be reused by any Plack based framework.

Saturday, February 19, 2011

Plack::Middleware::Auth::Form - like CatalystX::SimpleLogin but at Plack level.

I've just published a first version to github: zby / Plack-Middleware-Auth-Form. The authenticator parameter (and it's initialization) is copied from Plack::Middleware::Auth::Basic - this is a much simpler interface then Catalyst::Plugin::Authentication - but I think it can be enough.

The redirects from and to the login page are modeled after CatalystX::SimpleLogin.

t/app.psgi is the only example so far, but I plan to use it in Nblog.

Thursday, February 10, 2011

Is Newables/Injectables a fundamental distinction?

In To “new” or not to “new”… Misko Hevery advices us to divide object classes into Injectables and Newables. Newables are objects that cannot be injected with DI frameworks (that is by one type of DI frameworks), Injectables are those that can. The point is to build Injectables only from other Injectables and Newables only from other Newables. To complete this recursive definition the simple Newables are defined as objects that have attributes of only primitive types. It is not so clear what are the atomic Injectables. I guess technically this needs be classes with parameter-less constructors. The examples given suggest things that you get from the OS or external libraries like an audio device or socket, or database connection. Of course sockets are not really parameterless - you need to pass the port number as an argument to the external libraries that create one, neither are audio devices if you have more then one attached to your computer - so this will only work if we assume that the given program works with just one port number or only with '/dev/audio'. What if you wanted to test it on another port? And what if you wanted to have and object containing an array of available sockets - you could not pass the number of the sockets in its constructor, because this would spoil its Injectableness. Parameter-less constructors are only hiding globals.

This distinction between Newables and Injectables proves to be rather constraining - it would be much cleaner if every class (and indeed also primitive types) were Injectable. Fortunately it is only an artefact of the DI framework chosen - there are DI frameworks that can inject any value, because they find them by name not by type. In these frameworks all classes are Injectables - but it might still be useful to keep the name of Newables for objects that can be build internally without calling any external libraries.

Sunday, January 30, 2011

Returning to current page after login

This is one of the must have conveniences of a modern web-site: if a logged out user encounters a page that requires a login then - after logging in the user goes directly to that original page (instead of staying on the login page or going to some other predefined page). Here is a quick list of possible high-level solutions - anything missing? What is your choice?

1. No redirect


Either you have the login form on every page (a small one) - or you can display the login form instead of the page text if the login is required. You need more then a small box to fit in all the currently broadly used options like OpenId or logging in via Facebook - so for a universal solution you need a full page. Let's focus on displaying the login form on a page requiring authentication instead of that page content. This is a very simple solution - would it break any of the HTTP protocol rules? But then wouldn't displaying the error message saying 'Login required' break the same rule?

2. Passing the current url in the link to the login form


The minus of this solution is the ugly url of the login page. I also read somewhere that in some implementations there is a security problem - but I cannot find now any reference about it (it was something about crafting the uri param in a way that resulted in two http requests when the redirection was done).

3. Saving the current url in the session


Additionally to all the problems with sessions (and for example multiple tabs open to the site), there is a slight efficiency disadvantage if we do that for each link to the login page, because the session then needs to be saved every time. If the session is save to the database I imagine that this could have a slight impact.

4. Using the Referer HTTP header


This would also be quite simple - but can we rely on it? Additionally it would also require passing that url from that header back to the form for the case when the first login attempt fails. This can be done with hidden field - and since everyone uses POST for the login form method this would not spoil the login page url (or it can also be done with a session - but this time the session would be saved only in the case of a failed login).

This would only work if the user followed a link from the current page to the login page (presumably displayed together with the authentication required error message). But actually it is better to automate that step and:

5. Redirecting both to the login page and from it


This still requires saving the current page in the url (as in 2) or in the session (as in 3) - but without saving current url in the session at every page containing a link to the login page. It can also be combined with 4 if additionally to this mechanism we want to have have links to the login page that would lead the user back to the original page. From the user perspective this is as convenient as 1 but might be a bit more clean from the technology perspective (see Dave's comment below - although is 303 more correct here?). Anyway - this is the solution used by CatalystX::SimpleLogin (and Catalyst::ActionRole::NeedsLogin).

Updates: Added 5.

Monday, January 10, 2011

Is $ responsible for the 'ugliness' of Perl code?

We cannot hide it that Perl code is littered with the $ characters and, compared to the original well rounded Latin letters, that went through the thousands of years of tweaking to please the human eye, compared to them, $ is just an ugly hack. Unfortunately this is what people see when they first look at Perl code - lots of $ signs (by the way @ looks a bit better - maybe we should use more arrays?) - and this is how unconsciously they form the first impression about our language. This is not fair, this is so superficial - but the way the human mind works dictates that this first impression colours every information about Perl that comes later. People don't like to change their minds, and they always will find something to support what they thought initially, even if, or maybe the more so when, that initial thought was just an unconscious impression.

What can we do then? Changing the typeface of $ in the most popular web and editor fonts does not seem like a practical solution, but maybe if we show the sheer shallowness of judging the language by the shape of the typeface of some used character - maybe this would have some impact?

Update: Bear in mind that I don't advocate to get rid of $ in Perl - I find it very useful. The point is that the type face ugliness of $ can project a shadow on the whole language completely independently from it's usefulness as language construct.

Thursday, January 06, 2011

Dependency Injection - some updates

I finally found a succinct and clear definition of Dependency Injection:

Dependency injection means giving an object its instance variables instead of letting it create them.

based on answers to What is dependency injection? on Stackoverflow. There are some variations on how you do that - you can pass the instance variables in the call to the object creator (the new method) or you can use a setter to pass it to the object after it is created. This is exactly what I was thinking. Inversion of Control here happens only if you use a framework that takes over the object creation - but this is not required for the practice of DI. The name does not fit too well to its definition - but it is probably too late to change it.

Reasons to do DI:

  1. The most immediate reason is that it makes it easy to use mockups (or even undef's or Nulls) for the dependencies in tests. But this is is just a concrete example of the more general reasons that follow.
  2. To change the coupling between the main class and the dependency from control coupling to data-structured coupling (Types of coupling in wikipedia). Intuitively this also means increasing the encapsulation of the main module.
  3. To remove more frequently changing code from inside of less frequently changing code. There is an analogy between hardcoded literal constants and hardcoded objects - this is the main subject of my previous post.


It is worth noting that Moose by taking over the new method encourages DI, but of course people will always find ways to sidestep this by creating an init or setup method or using BUILD or BUILDARGS from the Moose API.

Tuesday, January 04, 2011

Dependency Injection or Removing Hardcoded Values?

Ever since I've heard about Dependency Injection (DI) a few years ago, I read and reread all the available documents and I kept having this feeling that I still miss something. Yesterday after some googling - I found that even those whom I always expected to explain things, have similar problems with it (see also this interesting reply to that rant). I am not sure if I now really understand DI, maybe I am still missing something important, but here is my tentative theory about it.

Let us say that somewhere deep in your web app code you have these lines:



Every minimally experienced programmer will notice immediately that for any re-usability the database name, user and his password should be extracted into a place where they can be changed easily, like the first lines of the program or better a config file. This would come very natural - but the reasoning behind it does not come from any theory - it is our experience that tells us that these pieces of data will change more frequently then the surrounding code.

I don't know if anyone would call this Dependency Injection, I think he would rather say that he is removing hardcoded constants.

Now let's take this snippet:



This is better - but the name of the DBI class and the way you construct the $dbh object is still hardcoded here - the point about DI is that this is still wrong because these parts also will change more often then the rest of the MyClass. The most important case for this is tests. In Perl it is possible to change the definition of the whole DBI package (mock it up) for the tests - but a more elegant solution is to move the database connection creation out of the MyClass code:



then, to test the MyClass methods that don't use the dbh field, you could pass an undef there and not bother with setting the database at all. But it is not only tests that require changes to that code - if for example at some point you decide that you want to log all the DBI warnings and add { PrintWarn => 1 } to the DBI->connect call - this would also be easier with this design. Again, just like with the initial example, I haven't seen any theory explaining this, but from my programming practice I am assured that this kind of change happens much more often, and at different phases of development, then changes to the rest of the MyClass code. Maybe the distinction is about what i.e. values (literals or objects) and how i.e. methods and subroutines - what is more expected and easier to change - and to get the advantage of that ease you cannot mix it together with how.

The code removed in the last sample is a bit more complicated then in the initial example - but at the core it has the same nature - it is about computing some values that are later used across a program part (or the whole program). In the initial example these values are literals, here they are objects. Literals can be created independently, objects depend on other objects: we can have a MyUser that depends on MyClass that (as in our example) depends on the database connection. Fortunately solving the dependency graph and finding out what needs to be created to have a MyUser object can be automated - this is what the various DI frameworks (like Bread::Board) do. In more 'strictly' typed languages like Java - this dependency graph is mostly defined by the types used, in Perl the dependency needs to be defined by the programmer explicitly - but the graph solving works in the same way. This is why this object creation code is (or can be made) quite simple and for all objects in the same scope it can fit into one package where you could adjust the various cooperating objects just like you do with the values of the configuration variables.

This is my understanding of Dependency Injection - maybe I am still missing something - but I don't see where, in any non-convoluted way, there is the Injection happening. There are no new dependencies injected into the code. Maybe more appropriate would Dependency Passing - as the dependencies are passed as parameters - but most of the work done when performing this refactorisation is removing parts of code, parameter passing is the trivial part. Additionally Inversion of Control, which is used to explain DI in many places, is just a minor characteristic of it, not very visible one and very different from other more common Inversion of Control occurrences. Mark Fawler coined the term Dependency Injection specifically to differ it from Inversion of Control in general - but I think that even presenting it as an example of IoC is misleading, because it is not very important to understand what is going on and it is so different from the Hollywood Principle that everyone thinks about when reading Inversion of Control. Finally what is frequently blurring explanations of DI is the details of the DI frameworks used and dwelling over constructor injections or setter injections - i.e. going into the how before the why is well explained.

I believe that removing hardcoded values is what Dependency Injection is really about. Most programmers already have good intuitions on why this is needed.