Monday 8 November 2010

firefox 4.0

the beta5 is working fairly well, and my favorite plugins like no-script, foxy-proxy and firebug work well. Firebug seems to have some documented minor issues but this does not affect to me.

FF4 has two big visible changes, the tabs on top (like google's chrome) and panorama view for grouping tabs (upper-right corner). This is a nice feature, but when you create several groups I have not found how to cycle between them without the mouse. For me is easier to put tabs in different windows and in my mac I can F10 to see the windows and select one (like in panorama when selecting between groups) but I can also alt-` to cycle between ff4 windows, so I can change swiftly between conceptualy grouped tabs, for example from the journals window to the bloger-mail window when writing an entry in my blog.

What I miss is an option to list all windows and tabs opened and be able to select the wanted one. This is just the opposit of when you start firefox from a stored session and an error occur and gives you the list of all the windows and tabs so you can deselect the unwanted one. This options should be somewhere but I have not discovered yet.

Sunday 7 November 2010

firefox 4.0 beta 6 (how to use it along firefox 3)

The firefox 4.0 beta is in the 6th release. This is the first ff4 release that I have tested.

Firefox uses only one process for all windows, so you can not open two different firefox at the same time. Well, you can but not with the same profile. So in order to use ff4 without losing my ff3 plugins and usability I need to create first a new profile and then a symlink to launch ff4.

  1.  first of all install ff4 with another name
    • I tried to raname ff4 in the dmg installer but was not possible, so used the terminal in my mac
    • cp -r firefox.app /Volumes/Macintosh\ HD/Applications/Firefox-4.0.app
  1.  Create a new profile
    • In my macOS (change your path for  linux or windows), open the terminal and type:
    • /Volumes/Macintosh\ HD/Applications/Firefox-4.0.app/Contents/MacOS/firefox-bin -profilemanager -no-remote
    • Then add a new profile "ff4"
  1. Create an alias in your .bashrc
    • alias ff4='/Volumes/Macintosh\ HD/Applications/Firefox-4.0.app/Contents/MacOS/firefox-bin -P ff4 -no-remote'
    • -no-remote tells firefox not to use the running instance but create a new one. You can use only one profile at a time though.
Note: you can copy your data from the older profile to the new one if you wish, or create a backup:
  • rsync -av ~/Library/Application\ Support/Firefox/Profiles/n6jajvmu.default  ~/personal/firefox_backup




    Thursday 7 October 2010

    [perl%dbi] find available drivers

    I have found a nice script to find out which are your available DBI drivers, in this page:

    http://defindit.com/readme_files/sqlite.html

    #!/usr/bin/perl
    use DBI;
    @driver_names = DBI->available_drivers();
    print "driver_names (apparently installed, available):\n";
    foreach my $dn (@driver_names)
    {
    print "$dn\n";
    }

    I have create a script with it and this is the output:
    $ perl find_dbi_drivers_installed.pl
    driver_names (apparently installed, available):
    DBM
    ExampleP
    File
    Gofer
    Proxy
    SQLite
    Sponge
    mysql






    EDITED[2010-10-08]:
    The previous script is a copy-paste from the web. Obviously I will add the use strict and will go inside a Utils module instead of a script.

    For single uses I will use a one-liner as the comments suggest. I like the perl 5.10 one-liner

    $ perl -MDBI -E 'say for DBI->available_drivers'

    especially the say for...

    Sunday 22 August 2010

    perl debugger and perl >5.10 features

    I have been using perl >5.10 for a long time and I use give/when and ~~ a lot. But when I try to debug my programs I get annoyed by the fact that I can not use this features in the debugger command line: Why I can not use these features directly in the debugger?? The debugger handle them very well when they are in the code but not in the command line.

    This is annoying because I am also get used to use the debugger as a REPL (yes, I know Devel::REPL but I have not installed it everywhere and I usually have a perl debugger already open in my emacs).

    After a lot of time avoiding the issue I asked it in stack overflow:

    How to use perl 5.10 features inside the debugger?

    and eldarerathis explained to me why

    perl -dEbug

    is not working:

    [ eldarerathis]
    I found a reference to the issue here, but it's about a year old. However, the relevant portion of the perl source hasn't changed since, and can be seen here.
    [...]
    Basically, the debugger is loaded before the -E flag is processed, so the features aren't yet enabled when the debugger gets loaded. The gist of this is that you can't currently use -E with the -d command. If you want to use say, switch, or any other feature from the debug prompt, you have to do it like this:
     
      DB<1> use feature 'say'; say "x"
      x

    Also seems that feature is lexically scoped so this does not work:

    DB<19> use feature 'say'
    DB<20> say 1
    Number found where operator expected at (eval 41)[/homes/pmg/pmg-soft/local-perl/lib/5.12.1/perl5db.pl:638] line 2, near "say 1"

    but this does:

    DB<21> use feature 'say';say 1
    1

    This is annoying because when debuggin perl >5.10 scripts, sometimes I need to fix a given/when, or a line with ~~ or copy-paste a line with say and it does not work :-(.

    If someone has any idea how to use new Perl code features in the debugger command line please let me know or answer in stack overflow.

    Friday 23 July 2010

    [perl] Rakudo Star will be available at the end of July

    Hopefully, Rakudo Star will be released at the end of the month.
    http://rakudo.org/node/73

    There is also a inline-rakudo (nice!)
    http://search.cpan.org/dist/Inline-Rakudo/lib/Inline/Rakudo.pm


    A nice excuse to play with perl6 during holidays

    Wednesday 21 July 2010

    nice blog entries about GWAS QC checks

    Three very nice blog entries from campus coworkers to read:

    First two about how to scrutinize GWAS, and one about the sociological, ethical and political issues of giving feedback to the DNA donors:

    * [Daniel MacArthur] Serious flaws revealed in "longevity genes" study
    * [Jeff Barret] How to read a genome-wide association study
    * [Vincent Plagnol] Communicating genetic data to DNA donors


    The points of the two first blog entries are relevant to the recent Nature paper
    Prepublication data sharing where one of the recommendations of the Toronto International Data Release Workshop is:

    Editors and reviewers

    As reviewers of manuscripts submitted for publication, scientists should be mindful that prepublication data sets are likely to have been released before extensive quality control is performed, and any unnoticed errors may cause problems in the analyses performed by third parties. Where the use of prepublication data is limited or not crucial to a study's conclusions, the reviewers should only expect the normal scientific practice of clear citation and interpretation. However, when the main conclusions of a study rely on a prepublication data set, reviewers should be satisfied that the quality of the data is described and taken into account in the analysis.

    Participants at the Toronto meeting recommended that journals play an active part in the dialogue about rapid prepublication data release (both in their formal guide to authors and informal instructions to reviewers). Journal editors should remind reviewers that large-scale data sets may be subject to specific policies regarding how to cite and use the data. Ultimately, journal editors must rely on their reviewers' recommendations for reaching decisions about publication. However, encouraging reviewers to carefully check the conditions for using data that authors have not created themselves can help to raise both the quality of analysis and fairness in citation of published studies.

    If the reviewers start to ask for these checks, studies using big consortium data (WTCCC etc) would be fine but studies would face serious problems if using data from small labs without web page or metadata information availability other than the supplementary information (if any) in a low impact paper. I wonder if would it be possible that resources like EGA , dbGAP or Gen2Phen would have tools to facilitate this checks to the users, referees and readers in the public metadata area (as the data is expected to be in any of these repositories) and have a very 'proactive attitude' asking for this kind of data as complete as possible to the submitter and backing this request with this nature or similar paper.


    Finally the image of the Daniel's entry comparing the science longevity paper Manhattan plot vs WTCCC Manhattan plots

    dot underscore files in mac tar files

    I have found a nasty issue taring files in a mac osX 10.5. When you tar the files sometimes tar creates a '._'  file for each of your files that stores all the metadata (similar to the .files when you copy to a non mac file system)

    http://arstechnica.com/apple/reviews/2005/04/macosx-10-4.ars/7

    Solution:

    add to your bash

    [for Tiger]
    export COPY_EXTENDED_ATTRIBUTES_DISABLE=true


    [for Leopard]
    (from http://aaronlongwell.com/2008/05/removing---dot-underscore-file.html)
    export COPYFILE_DISABLE=true

    Just in case you forgot to skip them, you can prevent the creation at extraction time with:
    tar -xzpvf mytarfile.tgz --exclude="._*"

    Saturday 17 July 2010

    some nice perl new links

    * Interview with Stevan Little (the creator of Moose)
    : http://perlcast.com/2010/07/12/stevan-little-on-moose/

    * Tim Bunce latest work
    ** NYTProf now can handle string evals and warn you about $&, $` etc (a must have module)
    :: http://blog.timbunce.org/2010/06/09/nytprof-v4-now-with-string-eval-x-ray-vision/
    :: http://blog.timbunce.org/2010/07/09/nytprof-4-04-came-saw-ampersand-and-conquered/
    ** Mirroring successful java classes into perl6
    :: http://blog.timbunce.org/2010/07/16/java2perl6api-java-to-perl-6-api-tranalation-what-why-and-whereto/

    Sunday 13 June 2010

    blogger html editor is owfully wrong!!!

    The blogger html editor is wrong and has evil desires to follow compose mode actions.

    Problem: blogger html/compose editor does not understand the css of the blog. So you can not preview your 'class' changes nor see the efects in Compose. Well, this is annoying by does not matter, I can use firebug for doing that and test the final look without publish it.

    But where this 'feature' is annoying is in the <pre> vs css: white-space:pre;

    If you have any text preformated but using a CSS class with "white-space:pre", that's ok and it works the first time. BUT.... if you try to edit it, it does not see any <pre> tag so it reformats the text and you loose all indentation!!!!

    Wednesday 9 June 2010

    ggplot2 course in statistics.com

    Dr. Hadley Wickham, the creator the fantastic R library ggplot2 has created an online course at statistics.com:

    http://www.statistics.com/ourcourses/ggplot2
    price $500

    Visualization in R with ggplot2

    Aim of Course:

    In this course, participants will learn how to use the ggplot R Project to make, format, label and adjust graphs using R. The ggplot2 Project, created by Hadley Wickham, is named after the term "Grammar of Graphics," which was coined by Leland Wilkinson (creator of Systat). This "grammar of graphics" is a system of describing and organizing the fundamental components of a graph and the process of creating a graph. Using ggplot2, participants will learn how to design and implement graphs in an efficient, elegant and systematic manner, following principles of general good graphing practice.

    Who Should Take This Course:

    Statistical analysts who use R and need to create or modify graphs.

    The Instructor:

    Dr. Hadley Wickham is the author of ggplot2: Elegant Graphics for Data Analysis (Use R) and a contributor to Cook & Swayne's Interactive and Dynamic Graphics for Data Analysis: Using R and GGobi (2007). His research interests include interactive and dynamic graphics, developing practical tools for data analysis, and in gaining better understanding of complex statistical models through visualization. An Assistant Professor at Rice University, Dr. Wickham has developed 15 R projects, and written numerous articles, chapters, and other papers and in 2006 he won the John Chambers Award for Statistical Computing for his work on the ggplot and reshape R packages.

    Saturday 5 June 2010

    tree map of the top 500 supercomputers

    http://news.bbc.co.uk/2/hi/technology/10187248.stm


    A nice tree map for visualizing different aspects of the the top500 supercomputers.

    A history of treemaps

    HTML5 and CSS3

    A nice report of the current state of the HTML5 and CSS3 status in the main browsers

    http://html5readiness.com/#ray-7

     Chrome and Safary missing 2 features, opera 4, firefox 8 and ie 'a lot'

    Tuesday 1 June 2010

    [perl] playing with Test::Trap

    In my previous post I was experimenting with Test::Exception. And as I wanted more flexibility reporting the errors (capturing $@) I am now exploring Test::Trap.

    Test::Trap has more control about trapping exceptions. It captures them in a object called by default $trap

    I have created the next code to test how Test::Trap stores the exceptions and how to retrieve them:

    !/usr/bin/env perl
    
    
    =head1 [progam_name]
    
     description:
    
    =cut
    
    use strict;
    use Bio::EnsEMBL::Utils::Exception qw(throw warning);
    use warnings;
    use Data::Dumper;
    use Test::More;
    use Test::Trap;
    
    plan tests => 3;
    
    my $ok;
    my $like_ok;
    
    $ok = trap {exception('die1')};
    
    # testing
    $like_ok = like($trap->die, qr/cause1/, 'testing exception("die1")');
    $like_ok? diag(debug_exception_ok($trap->die,3))
            : diag($ok? "not died but return: $ok" : 'died with: '.$trap->die());
    
    # testing
    $like_ok = like($trap->die, qr/cause2/, 'testing exception("die1")');
    $like_ok? diag(debug_exception_ok($trap->die,3))
            : diag($ok? "not died but return: $ok" : 'died with: '.$trap->die());
    
    $ok = trap {exception('live')};
    like($trap->die, qr/cause1/, 'testing exception("live") ');
    $like_ok? diag(debug_exception_ok($trap->die,3))
            : diag($ok? "not died but return: $ok" : 'died with: '.$trap->die());
    
    sub exception {
        my $txt = shift;
        $txt eq 'die1'? throw "cause1" : return $txt;
    }
    
    sub debug_exception_ok{
        my $txt = shift;
        my $num = shift;
        #$DB::single=1;
        # add the [ok] to help the output to be taken as ok
        my $msg = '[ok] ' . join ("\n[ok] ",(split "\n",$txt)[0..($num-1)]);
        return $msg;
    }
    

    * The first test was ok:
    $ok = trap {exception('die1')};
    
    # testing
    $like_ok = like($trap->die, qr/cause1/, 'testing exception("die1")');
    $like_ok? diag(debug_exception_ok($trap->die,3))
            : diag($ok? "not died but return: $ok" : 'died with: '.$trap->die());
    
    == output ==
    ok 1 - testing exception("die1")
    # [ok]
    # [ok] -------------------- EXCEPTION --------------------
    # [ok] MSG: cause1
    

    * the second test, when dying not by the condition tested but by another, then it is a bit over-verbose.
    not ok 2 - testing exception("die1")
    #   Failed test 'testing exception("die1")'
    #   at /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t line 31.
    #                   '
    # -------------------- EXCEPTION --------------------
    # MSG: cause1
    # STACK main::exception /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t:42
    # STACK main::__ANON__[/nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t:23] /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t:23
    # STACK Test::Trap::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:103] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:100
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276
    # STACK (eval) /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:109
    # STACK Test::Trap::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:112] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:109
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276
    # STACK Test::Trap::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:87] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:84
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276
    # STACK Test::Trap::Builder::TempFile::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder/TempFile.pm:33] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder/TempFile.pm:32
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:306] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:305
    # STACK Test::Trap::Builder::TempFile::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder/TempFile.pm:33] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder/TempFile.pm:32
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:306] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:305
    # STACK Test::Trap::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:147] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:146
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276
    # STACK (eval) /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:88
    # STACK Test::Trap::Builder::trap /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:88
    # STACK Test::Trap::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:39] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:38
    # STACK toplevel /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t:23
    # ---------------------------------------------------
    # '
    #     doesn't match '(?-xism:cause2)'
    
    [until here is the like() output: as it fails it prints the $trap->die. The thing
    that I don't like is that the regex tested is at the end of the ouptut]
    
    [now prints the 'cause of death' after the regex tested]
    # died with:
    # -------------------- EXCEPTION --------------------
    # MSG: cause1
    # STACK main::exception /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t:42
    # STACK main::__ANON__[/nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t:23] /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t:23
    # STACK Test::Trap::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:103] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:100
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276
    # STACK (eval) /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:109
    # STACK Test::Trap::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:112] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:109
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276
    # STACK Test::Trap::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:87] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:84
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276
    # STACK Test::Trap::Builder::TempFile::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder/TempFile.pm:33] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder/TempFile.pm:32
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:306] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:305
    # STACK Test::Trap::Builder::TempFile::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder/TempFile.pm:33] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder/TempFile.pm:32
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:306] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:305
    # STACK Test::Trap::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:147] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:146
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276
    # STACK (eval) /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:88
    # STACK Test::Trap::Builder::trap /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:88
    # STACK Test::Trap::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:39] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:38
    # STACK toplevel /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t:23
    # ---------------------------------------------------
    
    

    The problem with this second test with Test::Trap is that the throw() is over-verbose, and gets printed twice if I want to modify the exception output stored in Test::Trap object.

    One solution is report the test in a if..else. This is less elegant but do the job:
    # testing
    if (like($trap->die, qr/cause2/, 'testing exception("die1") for exception cause2') ){
        diag(debug_exception_ok($trap->die,3));
    }
    elsif($ok){
        diag( "not died but return: $ok");
    }
    
    #== output ==
    not ok 2 - testing exception("die1") for exception cause2
    #   Failed test 'testing exception("die1") for exception cause2'
    #   at /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t line 34.
    #                   '
    # -------------------- EXCEPTION --------------------
    # MSG: cause1
    # STACK main::exception /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t:49
    # STACK main::__ANON__[/nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t:22] /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t:22
    # STACK Test::Trap::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:103] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:100
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276
    # STACK (eval) /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:109
    # STACK Test::Trap::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:112] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:109
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276
    # STACK Test::Trap::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:87] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:84
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276
    # STACK Test::Trap::Builder::TempFile::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder/TempFile.pm:33] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder/TempFile.pm:32
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:306] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:305
    # STACK Test::Trap::Builder::TempFile::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder/TempFile.pm:33] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder/TempFile.pm:32
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:306] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:305
    # STACK Test::Trap::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:147] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:146
    # STACK Test::Trap::Builder::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:276
    # STACK (eval) /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:88
    # STACK Test::Trap::Builder::trap /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap/Builder.pm:88
    # STACK Test::Trap::__ANON__[/nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:39] /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Trap.pm:38
    # STACK toplevel /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t:22
    # ---------------------------------------------------
    # '
    #     doesn't match '(?-xism:cause2)'
    


    * Finally if the tested subrutine does not die, then the like() regular expression for the exception is in void scalar and raise a warning (not elegant)
    $ok = trap {exception('live')};
    like($trap->die, qr/cause1/, 'testing exception("live") ');
    $like_ok? diag(debug_exception_ok($trap->die,3))
    : diag($ok? "not died but return: $ok" : '');

    #== output==
    Use of uninitialized value in pattern match (m//)
    at /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t line 36.
    at /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t line 36
    eval '
    #line 36 /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t
    $test = $this =~ /$usable_regex/ ? 1 : 0
    ;' called at /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Builder.pm line 1119
    Test::Builder::_regex_ok('Test::Builder=HASH(0x9ba6a0)', 'undef', 'Regexp=SCALAR(0xf39f50)', '=~', 'testing exception("live") ') called at /nfs/users/nfs_p/pg4/local_perl/perllib/Test/Builder.pm line 803
    Test::Builder::like('Test::Builder=HASH(0x9ba6a0)', 'undef', 'Regexp=SCALAR(0xf39f50)', 'testing exception("live") ') called at /nfs/users/nfs_p/pg4/local_perl/perllib/Test/More.pm line 416
    Test::More::like('undef', 'Regexp=SCALAR(0xf39f50)', 'testing exception("live") ') called at /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t line 36
    not ok 3 - testing exception("live")
    # Failed test 'testing exception("live") '
    # at /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_trap.t line 36.
    # undef
    # doesn't match '(?-xism:cause1)'
    # not died but return: live


    I need the ' : diag($ok? "not died but return: $ok" : ''); ' in order to highligth that the die does not happen as expected and there would be an error in the sub or in the test itself.

    To sum up, despite the Test::Trap seems more flexible, Test::Exception just do the job clean and easier with Throws_ok

    [perl] playing with Test::Exception

    More about testing: handling exceptions


    Today I was updating some tests for my modules and I needed to test the exception handling. I was going to use 'eval{..}or do{..}' but decided to go for Try::Tiny, but once I entered in the path of using CPAN modules I decided to give a try (not pun intended) to Test::Exception.

    I have read about some people complaining about Test::Exception using prototypes and talking about this would lead to some unexpected behaviors in very uncommon situations. The author of Test::Exception also implemented the methods without prototypes (they are less attractive) but I don't know if not using the prototyped methods are free of the edge cases errors. Any way chromatic explained in this blog entry how the prototyped methods in Test::Exception works.

    Here I am playing with the test to see how can I handle the output of the tests:

    * First try

    Created a basic test "test_Test_Exception.t" to see if my method die

    use strict;
    #use warnings;
    #use Data::Dumper;
    use Test::More;
    use Test::Exception;

    plan tests => 3;

    my $ok;


    $ok = dies_ok (sub {die1()}
    , 'testing die1'
    );

    $ok = dies_ok (sub {die2()}
    , 'testing die2'
    );
    $ok = dies_ok (sub {live()}
    , 'testing live expecting die1'
    );

    sub die1 {
    die "cause1";
    }

    sub die2 {
    die "cause2"
    }

    sub live {
    return 1;
    }

    == result ==

    > perl test_Test_Exception.t
    1..3
    ok 1 - testing die1
    ok 2 - testing die2
    not ok 3 - testing live expecting die1
    # Failed test 'testing live expecting die1'
    # at /nfs/users/nfs_p/pg4/programming/perl/test_Test_Exception.t line 29.

    This is nice, if you expect something to die but doesn't, it tells you that.


    * Second try

    What would happen when you have some exceptions in a method and you want to test them and you want to be sure that they are the correct ones.

    You have throws_ok and you test for a regex of the output
    #
    ## trying throws_ok
    #
    $ok = throws_ok (sub {die1()}
    , qr/cause1/
    , 'testing die1'
    );

    $ok = throws_ok (sub {die2()}
    , qr/cause1/
    , 'testing die2 to see if die of cause 1'
    );
    $ok = throws_ok (sub {live()}
    , qr/cause1/
    , 'testing live expecting die1'
    );


    == result ==
    > perl test_Test_Exception.t
    1..3
    ok 1 - testing die1
    not ok 2 - testing die2 to see if die of cause 1
    # Failed test 'testing die2 to see if die of cause 1'
    # at /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_exception.pl line 41.
    # expecting: Regexp ((?-xism:cause1))
    # found: cause2 at /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_exception.pl line 86.
    not ok 3 - testing live expecting die1
    # Failed test 'testing live expecting die1'
    # at /nfs/users/nfs_p/pg4/programming/perl/playing_with_test_exception.pl line 45.
    # expecting: Regexp ((?-xism:cause1))
    # found: normal exit

    This is even better: test2 now fails if the exception text is not the expected one.


    * third try
    A more complicated case:
    I have a subrutine, and I test for one of the arguments but I tested for lowercase 'a' instead uppercase 'A'. But this subrutine has another exception and dies when second argument is 'B'

    #
    ## more about throws_ok
    #

    # testing an exception but obtaining other
    # error in the method: testing a instead A
    # - it should die when passing 'A' but does not die because that
    $ok1 = dies_ok (sub {die3('A', 'B')}
    , 'testing faulty method die3 with dies_ok: it should die BUT does it because another reason'
    );

    $ok2 = throws_ok (sub {die3('A', 'B')}
    , qr/because A/
    , 'testing faulty method die3 with throws_ok it should die BUT does it because another reason'
    );

    # testing the other exception
    $ok3 = throws_ok (sub {die3( undef,'B')}
    , qr/because B/
    , 'testing faulty method die3 with throws_ok for another exception that works ok'
    );

    # testing exception but an error in the test (wrong argument so it does not die)
    $ok4 = dies_ok (sub {die3( undef)}
    , 'testing faulty test for die3: should die but it doesn\'t'
    );


    $ok5 = throws_ok (sub {die3( undef)}
    , qr/because A/
    , 'testing faulty test for die3: should die but it doesn\'t'
    );


    sub die3 {

    my $in = shift;
    my $out = shift;

    # [error] testing if $in eq A but testing eq 'a' instead
    die "die because A" if $in eq 'a';

    # ups sometimes something else goes wrong
    if ( $out eq "B" ) {
    die "die because BLAH";
    }

    return "live";
    }


    == results ==

    # with dies_ok wrong result, it is happy with the death (but by the wrong motives :-():
    ok 1 - testing faulty method die3 with dies_ok: it should die BUT does it because another reason

    # but the expected result (failed) with throws_ok
    not ok 2 - testing faulty method die3 with throws_ok it should die BUT does it because another reason
    # Failed test 'testing faulty method die3 with throws_ok it should die BUT does it because another reason'
    # at /nfs/users/nfs_p/pg4/programming/perl/test_Test_Exception.t line 61.
    # expecting: Regexp ((?-xism:because A))
    # found: die because BLAH at /nfs/users/nfs_p/pg4/programming/perl/test_Test_Exception.t line 100.

    #
    ok 3 - testing faulty method die3 with throws_ok for another exception that works ok

    # it fails because not die
    not ok 4 - testing faulty test with dies_ok for die3: should die but it doesn't
    # Failed test 'testing faulty test for die3: should die but it doesn't'
    # at /nfs/users/nfs_p/pg4/programming/perl/test_Test_Exception.t line 73.

    # It fails because does not die at all and tell you that: "found: normal exit"
    not ok 5 - testing faulty test with throws_ok for die3: should die but it doesn't
    # Failed test 'testing faulty test for die3: should die but it doesn't'
    # at /nfs/users/nfs_p/pg4/programming/perl/test_Test_Exception.t line 77.
    # expecting: Regexp ((?-xism:because A))
    # found: normal exit

    The throws_ok is more informative and prevents to think that your test failed as expected when indeed was not "as expected" but because another reason.



    This is fine, but if I want double check the output messages for the exceptions when debugging, I need to add the 'and diag($@)' or if I want to see if it failed because other exception or because it didn't die I need to do the following:

    my $ok = throws_ok( sub {...}, qr/check/, 'test desc') 
              or do {$@? diag("FAILED:\n Wrong exception.") 
                       : diag("FAILED:\n it was suppose to die")
                    };
     diag("Exception_ok:\n". lines($@,3)) if $ok; 
    
     sub lines{
       my $txt = shift;
       my $num = shift;
       # add the [ok] to help the output to be taken as ok
       my $msg = '[ok] ' . join ("\n[ok] ",(split "\n",$txt)[0..($num-1)]);
       return $msg;
     }
    

    And then you would have output like this for failed tests:

    not ok 5 - \#Should die: parse_tab_file_to_AoH without headers array ref:
    # Failed test '\#Should die: parse_tab_file_to_AoH without headers array ref: '
    # at PMGBase.t line 69.
    # expecting: Regexp ((?-xism:but not \$headers))
    # found: normal exit
    # FAILED:
    # it was suppose to die
    not ok 6 - \#Should die: parse_tab_file_to_AoH without headers array ref:
    # Failed test '\#Should die: parse_tab_file_to_AoH without headers array ref: '
    # at PMGBase.t line 76.
    # expecting: Regexp ((?-xism:but no \$headers))
    # found:
    # -------------------- EXCEPTION --------------------
    # MSG: # [FATAL] sorry but 'parse_tab_file()' called with type 'AoH' but not $headers_aref provided
    #
    # STACK PMGBase::_throw ..//PMGBase.pm:498
    # STACK PMGBase::parse_tab_file ..//PMGBase.pm:612
    # STACK PMGBase::parse_tab_file_to_AoH ..//PMGBase.pm:561
    # STACK Test::Exception::throws_ok PMGBase.t:73
    # STACK toplevel PMGBase.t:76
    # ---------------------------------------------------
    # FAILED:
    # Wrong exception.

    And some debug info for the ones ok:

    ok 7 - \#Should die: parse_tab_file_to_AoH without headers array ref:
    # Exception_ok:
    # [ok]
    # [ok] -------------------- EXCEPTION --------------------
    # [ok] MSG: # [FATAL] sorry but 'parse_tab_file()' called with type 'AoH' but not $headers_aref provided

    ok 9 - \#Should die: parse_tab_file_to_AoH with wrong number of header columns:
    # Exception_ok:
    # [ok]
    # [ok] -------------------- EXCEPTION --------------------
    # [ok] MSG: line 2 has different number of columns that the header


    Next step is to explore the Test::Trap that seems that have better layers for handling and reporting the exceptions. But at the moment if you want a simple ok/fail for exceptions Test::Exception is very handy.

    Tuesday 18 May 2010

    [Perl] Removig spaces from strings

    Thanks to Fred Moyer in the PerlMongers at LinkedIn I learned about the existence of the module:
    String::Strip

    It uses XS to remove spaces from a string and claims to be 35% faster.

    You can also trim your text withText::Trim.

    I would prefer to use modules for typical patterns but here a simple s/^\s+|\s+$//g will do the trick and I have it in my Emacs macros for a "sub trim {...}" ;-). This would be nanosecond slower than other approximations but trimming is not my bottleneck, db accession is :-(.
    [update 210-06-13]
    Tom Christiansen in "Perl Cookbook, 2nd Edition"

    --Recipe 1.19. Trimming Blanks from the Ends of a String--

    show another aproximation:
    If the function isn't passed any arguments at all, it could act like chop and chomp by defaulting to $_. Incorporating all of these embellishments produces this function:
    # 1. trim leading and trailing white space
    # 2. collapse internal whitespace to single space each
    # 3. take input from $_ if no arguments given
    # 4. join return list into single scalar with intervening spaces 
    #     if return is scalar context
    
    sub trim {
        my @out = @_ ? @_ : $_;
        $_ = join(' ', split(' ')) for @out;
        return wantarray ? @out : "@out";
    }
    

    PD:
    I would need to update my trim sub at some point (following PBP) to something like
    s/A\s+|\s+z//gms
    But I would need to check that it would do the right thing, and remove spaces before and after "\n"

    * Posted by David Bouman in perlmongers at linkedIn:
    sub trim { return unpack 'A*', reverse unpack 'A*', reverse shift }

    * Posted by Tobie Van Der Merwe in perlmongers at linkedIn:

    Tobie solves the problem doing more work that needed and instead doing eliminating white space directly he captures the text in between. Probably this is not elegant and a bit complicated (see Gabor reply) but on the other hand he has shown a good perl attitude and one not so good.

    The good one: always give a test case and the code to proof your code. Probably he had not the knowledge for a better regex but he had a good attitude .

    The not so good one: if you do a complex regex with some tricky parts (non greedy quantifiers) you should use /x and put comments.

    [Tobie] I think it can be solved with a regex -

    # Short program to test left and right
    # trim regex - s/^[\s]*(.*?)[\s]*$/$1/

    my %tests = ( 1 => 'This is great',
    2 => 'This is great ',
    3 => ' This is great',
    4 => ' This is great ',
    5 => ' 12345AA 22277 ',
    6 => ' !^%&^"$ ^777% ');

    foreach my $num (sort keys (%tests)) {
    print "BEFORE[" . $tests{$num} . "]\n";
    $tests{$num} =~ s/^[\s]*(.*?)[\s]*$/$1/;
    print "AFTER [" . $tests{$num} . "]\n";
    }


    * Gábor Szabó reply:

    Looking at s/^[\s]*(.*?)[\s]*$/$1/
    besides the fact that the square brackets [] around the \s are not necessary and only make noise it one of the examples I am using to show that you do NOT have to do everything with one regex.

    This solution is both complex and error prone - sanjeev indeed missed out on the ? that turns the otherwise greedy quantifier into minimal matching. You can of course use as TMTOWDI but then don't be surprised if people think Perl is cryptic.

    Lastly, really, is trimming whitespace such an important task that it justifies 60 posts?

    some perl modules for web testing and scrapping

    perl modules for web testing


    Some modules and its links to do web testing and web automation. There has been a long time since I was doing a lot of web scrapping in the past(parsing webs with locus specific genetic mutations), and now I need it to do it again. So I am trying to find out which are the latest modules for web scrapping and refresh my memory.

    This is my first list of modules to explore. I will post later my progress in this issue.

    * HTTP:WebTest
    : http://search.cpan.org/~ilyam/HTTP-WebTest-2.04/lib/HTTP/WebTest.pm

    * HTTP::Recorder
    : http://search.cpan.org/~leira/HTTP-Recorder-0.05/lib/HTTP/Recorder.pm
    : http://www.perl.com/lpt/a/845
    : http://www.perl.com/pub/a/2004/06/04/recorder.html

    * WWW::Mechanize
    : http://search.cpan.org/~petdance/WWW-Mechanize-1.62/lib/WWW/Mechanize.pm
    : http://www.perl.com/pub/a/2003/01/22/mechanize.html
    :: There is a Test::WWW::Mechanize

    * Web::Scraper
    : http://search.cpan.org/~miyagawa/Web-Scraper-0.32/
    : http://use.perl.org/articles/07/10/04/2021216.shtml
    : http://teusje.wordpress.com/2010/05/02/web-scraping-with-perl/

    * WWW::Scripter
    : http://search.cpan.org/~sprout/WWW-Scripter-0.010/lib/WWW/Scripter.pod

    Special mention deserves pQuery a port of jQuery to perl:
    * pQuery
    : http://search.cpan.org/~ingy/pQuery-0.07/lib/pQuery.pm

    [from the pQuery's CPAN page]

    The power of jQuery is that single method calls can apply to many DOM objects. pQuery does the exact same thing but can take this one step further. A single PQUERY object can contain several DOMs!

    Consider this example:

    &gt; perl -MpQuery -le 'PQUERY(\
    map "http://search.cpan.org/~$_/", qw(ingy gugod miyagawa))\
    -&gt;find("table")-&gt;eq(1)-&gt;find("tr")\
    -&gt;EACH(sub{\
        printf("%40s - %s Perl distributions\n", $_-&gt;url, $_-&gt;length - 1)\
    })'
    
    [out]
    http://search.cpan.org/~ingy/ - 88 Perl distributions
    http://search.cpan.org/~gugod/ - 86 Perl distributions
    http://search.cpan.org/~miyagawa/ - 138 Perl distributions
    The power lies in PQUERY, a special constructor that creates a wrapper object for many pQuery objects, and applies all methods called on it to all the pQuery objects it contains.

    ===============

    -- summary from  http://stackoverflow.com/questions/713827/how-can-i-screen-scrape-with-perl


    ----------------
    If you are familiar with jQuery you might want to check out pQuery, which makes this very easy:
    ## print every tag in page
    
    use pQuery;
    
    pQuery("http://google.com/search?q=pquery")-&gt;find("h2")-&gt;each(
        sub {
           my $i = shift;
           print $i + 1, ") ", pQuery($_)-&gt;text, "\n";
        });
    
    There's also HTML::DOM.


    ===============
    use LWP;
    use HTTP::Cookies;
    my $cookie_jar = HTTP::Cookies-&gt;new;
    my $browser = LWP::UserAgent-&gt;new;
    $browser-&gt;cookie_jar($cookie_jar);
    $resp = $browser-&gt;get("https://www.stackoverflow.com");
    if($resp-&gt;is_success) {
       # Play with your source here
       $source = $resp-&gt;content;
       $source =~ s/^.*/i; # this is just an example
       print $source;      # not a solution to your problem. 
    }
    
    ==========
    use HTML::TableExtract;
    $te = HTML::TableExtract-&gt;new();
    $te-&gt;parse($html_string);
    
    # Examine all matching tables
    foreach $ts ($te-&gt;tables) {
        print "Table (", join(',', $ts-&gt;coords), "):\n";
        foreach $row ($ts-&gt;rows) {
            print join(',', @$row), "\n";
        }
    }
    


    ========

    [UPDATES]


    Thanks to @kiran I learned about Selenium

    [here from the CPAN:]

    NAME ^

    WWW::Selenium - Perl Client for the Selenium Remote Control test tool

    SYNOPSIS ^

    use WWW::Selenium;
        
        my $sel = WWW::Selenium-&gt;new( host =&gt; "localhost", 
                                      port =&gt; 4444, 
                                      browser =&gt; "*iexplore", 
                                      browser_url =&gt; "http://www.google.com",
                                    );
        
        $sel-&gt;start;
        $sel-&gt;open("http://www.google.com");
        $sel-&gt;type("q", "hello world");
        $sel-&gt;click("btnG");
        $sel-&gt;wait_for_page_to_load(5000);
        print $sel-&gt;get_title;
        $sel-&gt;stop;

    DESCRIPTION ^

    Selenium Remote Control (SRC) is a test tool that allows you to write automated web application UI tests in any programming language against any HTTP website using any mainstream JavaScript-enabled browser. SRC provides a Selenium Server, which can automatically start/stop/control any supported browser. It works by using Selenium Core, a pure-HTML+JS library that performs automated tasks in JavaScript; the Selenium Server communicates directly with the browser using AJAX (XmlHttpRequest).
    http://www.openqa.org/selenium-rc/
    This module sends commands directly to the Server using simple HTTP GET/POST requests. Using this module together with the Selenium Server, you can automatically control any supported browser.
    To use this module, you need to have already downloaded and started the Selenium Server. (The Selenium Server is a Java application.)

    [2010-05-20] from @anonymous, he pointed to HTML::Query


    NAME ^

    HTML::Query - jQuery-like selection queries for HTML::Element

    SYNOPSIS ^

    Creating an HTML::Query object using the Query() constructor subroutine:
    use HTML::Query 'Query';
        
        # using named parameters 
        $q = Query( text  =&gt; $text  );          # HTML text
        $q = Query( file  =&gt; $file  );          # HTML file
        $q = Query( tree  =&gt; $tree  );          # HTML::Element object
        $q = Query( query =&gt; $query );          # HTML::Query object
        $q = Query(                             
            text  =&gt; $text1,                    # or any combination
            text  =&gt; $text2,                    # of the above
            file  =&gt; $file1,
            file  =&gt; $file2,
            tree  =&gt; $tree,
            query =&gt; $query,
        );
    
        # passing elements as positional arguments 
        $q = Query( $tree );                    # HTML::Element object(s)
        $q = Query( $tree1, $tree2, $tree3, ... );  
        
        # or from one or more existing queries
        $q = Query( $query1 );                  # HTML::Query object(s)
        $q = Query( $query1, $query2, $query3, ... );
        
        # or a mixture
        $q = Query( $tree1, $query1, $tree2, $query2 );
    
        # the final argument (in all cases) can be a selector
        my $spec = 'ul.menu li a';  # <ul class="menu">..<li>..<a>
        
        $q = Query( $tree, $spec );
        $q = Query( $query, $spec );
        $q = Query( $tree1, $tree2, $query1, $query2, $spec );
        $q = Query( text  => $text,  $spec );
        $q = Query( file  => $file,  $spec );
        $q = Query( tree  => $tree,  $spec );
        $q = Query( query => $query, $spec );
        $q = Query( 
            text => $text,
            file => $file,
            # ...etc...
            $spec 
        );
    
    

    DESCRIPTION ^

    The HTML::Query module is an add-on for the HTML::Tree module set. It provides a simple way to select one or more elements from a tree using a query syntax inspired by jQuery. This selector syntax will be reassuringly familiar to anyone who has ever written a CSS selector.
    HTML::Query is not an attempt to provide a complete (or even near-complete) implementation of jQuery in Perl (see Ingy's pQuery module for a more ambitious attempt at that). Rather, it borrows some of the tried and tested selector syntax from jQuery (and CSS) that can easily be mapped onto the look_down() method provided by the HTML::Element module.

    Tuesday 11 May 2010

    European Nucleotide Archive

    The European Bioinformatics Archive (EBI) at Cambridge, UK, has recently launched the European Nucleotide Archive (ENA). This Archive puts together all previous nucleotide services at EBI (EMBL-Bank, ERA, etc.)



    Press release:
    http://www.ebi.ac.uk/Information/News/pdf/Press10May10.pdf


    Please update your links!!!!

    Official Email:

    Hello all,

    The EBI has launched the European Nucleotide Archive(ENA; http://www.ebi.ac.uk/ena/). The press release is
    available here (http://www.ebi.ac.uk/Information/News/pdf/Press10May10.pdf).The European Nucleotide Archive is the new collective name for the
    archival nucleotide sequence databases and services that have been
    operated from this campus over many years, including annotated and
    assembled sequence (EMBL-Bank) and raw data (Trace Archive and Sequence
    Read Archive). The new service includes graphical browsing, programmatic
    services, next generation sequencing support, text search and a new
    rapid sequence similarity search.

    We are grateful for feedback and can provide help in using ENA - please
    contact us at datasubs@ebi.ac.uk.


    Referring to ENA
    ----------------
    From now on, our services should be referred to as the 'European Nucleotide Archive' or 'ENA'.

    We prefer that 'ENA' be used when referring to all data types that we
    cover (eg. 'raw data and assemblies were submitted to ENA', 'annotation
    downloaded from ENA'), but we accept that some usage of existing
    component database names, such as EMBL-Bank, will be necessary at least
    for some time.

    Accession numbers are unique across all data classes within ENA. When
    pointing to records, it is only therefore necessary to cite the
    namespace and the accession number: 'ENA:', eg. 'ENA:BN000065'.


    Pointing to ENA records
    -----------------------
    URLs to resolve all ENA records by accession take the form:
    http://www.ebi.ac.uk/ena/data/view/,
    egs.
    http://www.ebi.ac.uk/ena/data/view/BN000065
    http://www.ebi.ac.uk/ena/data/view/ERA000092
    http://www.ebi.ac.uk/ena/data/view/TI1288391363

    Many further options are supported for HTTP access and are described in
    http://www.ebi.ac.uk/ena/about/page.php?page=browser.

    We will continue to support existing URL syntax for our component
    databases for some time, but would ask that you update any links that you provide as soon as possible.


    Thanks for using ENA,

    Guy Cochrane.

    Sunday 9 May 2010

    Neandertal genome

    The Neandertal genome draft has been published in science:


    http://www.sciencemag.org/cgi/content/full/328/5979/710


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


    Science. 2010 May 7;328(5979):710-22.

    A draft sequence of the Neandertal genome.

    Department of Evolutionary Genetics, Max-Planck Institute for Evolutionary Anthropology, D-04103 Leipzig, Germany. green@eva.mpg.de
    Comment in:

    Abstract

    Neandertals, the closest evolutionary relatives of present-day humans, lived in large parts of Europe and western Asia before disappearing 30,000 years ago. We present a draft sequence of the Neandertal genome composed of more than 4 billion nucleotides from three individuals. Comparisons of the Neandertal genome to the genomes of five present-day humans from different parts of the world identify a number of genomic regions that may have been affected by positive selection in ancestral modern humans, including genes involved in metabolism and in cognitive and skeletal development. We show that Neandertals shared more genetic variants with present-day humans in Eurasia than with present-day humans in sub-Saharan Africa, suggesting that gene flow from Neandertals into the ancestors of non-Africans occurred before the divergence of Eurasian groups from each other.
    PMID: 20448178 [PubMed - in process]

    Thursday 29 April 2010

    How to concatenate files without the headers with perl

    == Problem: ==
    You have hundreds of files with a header and you want to concatenate
    all of them without the headers except the first one

    ==Solution(s)==

    === Perl one-liner ===


    $ ls
    file.1 file.2 file.3 file.4 ...

    # create a file with the header
    # print only the first line of one of the files and
    # redirect ('>') to the final file

    $ head -n 1 file.1 > concatenated.file

    # loop for all the files and print all lines except first one ($.==1)
    # if your files have numeric suffixes and are correlative use `seq`
    # if not use `find`, `ls | grep` etc ('find' is more secure than 'ls' [google for it])
    ## (be careful with `ls` if your filenames are not non-space or non-ascii)

    ### TCSH
    $ foreach x ( `seq 1 10` )
    foreach? echo $x
    foreach? perl -lne 'print if $.>1' file.$x >> concatenated.file
    foreach? end

    ### BASH
    $ for x in ($(seq 1 10));do echo $x; \
    perl -lne 'print if $.>1' file.$x >> concatenated.file; done

    #or
    $ echo {1..10}| xargs -n1 -t -I'{}' perl -lne 'print if $.>1' file.'{}' >> concat

    ## better to use xargs than a loop but is more difficult to have all in a one-liner
    ## because quotes problems when you need to do complicated things, or the redirection
    ## file needs also to use the loop variable.


    === Only non-perl commands (faster and shorter) ===


    # you can use 'find ... -exec ...' or
    # use tail -n+
    $ head -n1 file.1 > concatenated.file
    $ tail -q -n+2 file.* >> concatenated.file'

    # the tail -q prevents to output the file name
    # the tail -n+2 takes from second line to the end

    # if the order of the numeric suffixes is important (the * expansion puts 10 before 2)
    # you should rename the files
    # and convert 1,2,...,10 to 01,02,..,10 with rename and "sprintf "%02d",$suff'
    # or use a loop with the correct order of suffixes [ for x in $(seq 1 22)].

    Friday 16 April 2010

    perl smart matching (copied from perlsyn.pod)

    Smart matching in detail

    The behaviour of a smart match depends on what type of thing its arguments are. The behaviour is determined by the following table: the first row that applies determines the match behaviour (which is thus mostly determined by the type of the right operand). Note that the smart match implicitly dereferences any non-blessed hash or array ref, so the "Hash" and "Array" entries apply in those cases. (For blessed references, the "Object" entries apply.)
    Note that the "Matching Code" column is not always an exact rendition. For example, the smart match operator short-circuits whenever possible, but grep does not.
    $a      $b        Type of Match Implied    Matching Code
        ======  =====     =====================    =============
        Any     undef     undefined                !defined $a
    
        Any     Object    invokes ~~ overloading on $object, or dies
    
        Hash    CodeRef   sub truth for each key[1] !grep { !$b->($_) } keys %$a
        Array   CodeRef   sub truth for each elt[1] !grep { !$b->($_) } @$a
        Any     CodeRef   scalar sub truth          $b->($a)
    
        Hash    Hash      hash keys identical (every key is found in both hashes)
        Array   Hash      hash keys intersection   grep { exists $b->{$_} } @$a
        Regex   Hash      hash key grep            grep /$a/, keys %$b
        undef   Hash      always false (undef can't be a key)
        Any     Hash      hash entry existence     exists $b->{$a}
    
        Hash    Array     hash keys intersection   grep { exists $a->{$_} } @$b
        Array   Array     arrays are comparable[2]
        Regex   Array     array grep               grep /$a/, @$b
        undef   Array     array contains undef     grep !defined, @$b
        Any     Array     match against an array element[3]
                                                   grep $a ~~ $_, @$b
    
        Hash    Regex     hash key grep            grep /$b/, keys %$a
        Array   Regex     array grep               grep /$b/, @$a
        Any     Regex     pattern match            $a =~ /$b/
    
        Object  Any       invokes ~~ overloading on $object, or falls back:
        Any     Num       numeric equality         $a == $b
        Num     numish[4] numeric equality         $a == $b
        undef   Any       undefined                !defined($b)
        Any     Any       string equality          $a eq $b
    
     1 - empty hashes or arrays will match.
     2 - that is, each element smart-matches the element of same index in the
         other array. [3]
     3 - If a circular reference is found, we fall back to referential equality.
     4 - either a real number, or a string that looks like a number

    perl 5.12 is out


    == perl 5.12 ==

    [http://search.cpan.org/~jesse/perl-5.12.0/pod/perl5120delta.pod]

    many of the changes where already added in 5.10.1

    but a few new things:

    * strict by default if 5.12 asked
    : use 5.12.0;
    : # it adds the 'use strict'

    * $VERSION could be defined in the 'package line'
    : package Foo::Bar 1.23;

    * unicode
    : uses Unicode 5.2,

    * \N experimental regex escape
    : the contrary to \n (it could class with the unicode \N{name} this is
    : the reason why it is experimental)

    * each
    : each could now operate on arrays

    * delete local
    : delete local now allows you to locally delete a hash entry.



    * yada yada operator
    : http://search.cpan.org/~jesse/perl-5.12.0/pod/perlop.pod#Yada_Yada_Operator___
    [copy from perlop.pod]
    The yada yada operator (noted ...) is a placeholder for code. Perl parses it without error, but when you try to execute a yada yada, it throws an exception with the text Unimplemented:
    sub unimplemented { ... }
            
            eval { unimplemented() };
            if( $@ eq 'Unimplemented' ) {
              print "I found the yada yada!\n";
              }
    You can only use the yada yada to stand in for a complete statement. These examples of the yada yada work:
    { ... }
            
            sub foo { ... }
            
            ...;
            
            eval { ... };
            
            sub foo {
                            my( $self ) = shift;
                            
                            ...;
                            }
                            
            do { my $n; ...; print 'Hurrah!' };
    The yada yada cannot stand in for an expression that is part of a larger statement since the ... is also the three-dot version of the range operator (see "Range Operators"). These examples of the yada yada are still syntax errors:
    print ...;
            
            open my($fh), '>', '/dev/passwd' or ...;
            
            if( $condition && ... ) { print "Hello\n" };
    There are some cases where Perl can't immediately tell the difference between an expression and a statement. For instance, the syntax for a block and an anonymous hash reference constructor look the same unless there's something in the braces that give Perl a hint. The yada yada is a syntax error if Perl doesn't guess that the { ... } is a block. In that case, it doesn't think the ... is the yada yada because it's expecting an expression instead of a statement:
    my @transformed = map { ... } @input;  # syntax error
    You can use a ; inside your block to denote that the { ... } is a block and not a hash reference constructor. Now the yada yada works:
    my @transformed = map {; ... } @input; # ; disambiguates
    
            my @transformed = map { ...; } @input; # ; disambiguates

    Saturday 10 April 2010

    managing multiple local perl installations: perlbrew

    Gugod script for managing different local perl installations:


    I have my perl 5.10.1 installed with local::lib and was planing to install the 5.12RC. This is an opportunity to try the Gugod app:

    App::perlbrew Manage perl installations in your $HOME

    This has a nice way of changing between perl version. I have not tried yet but from the perldoc it seems easy and clean.

    Copied from the SYNOPSIS:


    # Initialize
    perlbrew init

    # Install some Perls
    perlbrew install perl-5.8.1
    perlbrew install perl-5.11.5

    # See what were installed
    perlbrew installed

    # Switch perl in the $PATH
    perlbrew switch perl-5.11.5
    perl -v

    # Switch to another version
    perlbrew switch perl-5.8.1
    perl -v

    # Switch to a certain perl executable not managed by perlbrew.
    perlbrew switch /usr/bin/perl

    # Or turn it off completely. Useful when you messed up too deep.
    perlbrew off

    # Use 'switch' command to turn it back on.
    perlbrew switch perl-5.11.5

    perl Bio::Graphics module dependencies in ubuntu 9.04

    Following my previous posts I am puting this here for future googling ;-).

    These are the failed dependencies that I had when I tried the CPAN install Lincon Stein's Bio::Graphic (in a fresh installed linux box). I need to say that I have installed Bioperl and Bio::Graphics in all my developing machines and laptops many times and usually it works without problems at the first go, but this is because I usually had a lot of things already installed.

    But now when I have run CPAN install Bio::Graphics in a clean box I have had a lot of 'expected' dependence issues:


    Failed during this command:
    MSERGEANT/XML-Parser-2.36.tar.gz : make NO
    MKUTTER/SOAP-Lite-0.710.10.tar.gz : make_test NO
    LBROCARD/GraphViz-2.04.tar.gz : writemakefile NO '/home/pablo/localperl/bin/perl Makefile.PL' returned status 512
    MIROD/XML-Twig-3.32.tar.gz : make_test NO
    PMQS/DB_File-1.820.tar.gz : make NO
    KMACLEOD/libxml-perl-0.08.tar.gz : make_test NO
    TJMATHER/XML-DOM-1.44.tar.gz : make_test NO
    MIROD/XML-DOM-XPath-0.14.tar.gz : make_test NO
    CJFIELDS/BioPerl-1.6.1.tar.gz : make_test NO
    LDS/GD-2.44.tar.gz : writemakefile NO '/home/pablo/localperl/bin/perl Makefile.PL' returned status 512
    LDS/Bio-Graphics-1.994.tar.gz : make_test NO


    Then I needed to install this:

    * sudo aptitude install
    - libgd2-xpm-dev # gd for GD. I don't know the difference between xpm and noxpm but anyway
    - libexpat-dev # expat for XML::Parser
    - graphviz graphviz-dev graphviz-doc libgraphviz-dev graphviz-cairo # for GraphViz
    - libdb4.6-dev # for DB_File (The headers for 4.7 were also available but I had 4.6 installed)


    And this CPAN modules in this order:

    *CPAN
    - install IPC::Run # for GraphViz and other modules
    - install DB_File # used by several modules so it better to install it first
    - install XML::parser
    - install GraphViz
    - install GD
    - install CJFIELDS/BioPerl-1.6.1.tar.gz

    And then I was able to install Bio::Graphics

    The only caveats here are that you should know that you need the expat for XML, IPC::Run for GraphViz dependency and that DB_File uses the Berkeley db headers (that I needed to google for finding the package that contains them).

    Friday 9 April 2010

    Installing Bioperl 1.6.1 from CPAN in ubuntu 9.04: fixing DB_File failed dependency

    I was unable to install BioPerl 1.6.1 from CPAN. DB_File dependence was not compiling.

    DB_FILE was failing because I don't have db.h in my ubuntu 9.04



    cpan[4]> install DB_File
    [...]
    CPAN.pm: Going to build P/PM/PMQS/DB_File-1.820.tar.gz

    Parsing config.in...
    Looks Good.
    Checking if your kit is complete...
    Looks good
    Note (probably harmless): No library found for -ldb
    Writing Makefile for DB_File
    cp DB_File.pm blib/lib/DB_File.pm
    AutoSplitting blib/lib/DB_File.pm (blib/lib/auto/DB_File)
    cc -c -I/usr/local/BerkeleyDB/include -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -DVERSION=\"1.820\" -DXS_VERSION=\"1.82\" -fPIC "-I/home/pablo/localperl/lib/5.10.1/i686-linux/CORE" -D_NOT_CORE -DmDB_Prefix_t=size_t -DmDB_Hash_t=u_int32_t version.c
    version.c:30:16: error: db.h: No such file or directory
    make: *** [version.o] Error 1
    PMQS/DB_File-1.820.tar.gz
    /usr/bin/make -- NOT OK
    Running make test
    Can't test without successful make
    Running make install
    Make had returned bad status, install seems impossible
    Failed during this command:
    PMQS/DB_File-1.820.tar.gz : make NO


    So it is missing the db.h file.


    > sudo aptitude install libdb4.6-dev
    $ perl Makefile.PL
    Parsing config.in...
    Looks Good.
    Writing Makefile for DB_File


    Now it is ok:


    > make
    > make test
    PERL_DL_NONLAZY=1 /home/pablo/localperl/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
    t/db-btree.t .. ok
    t/db-hash.t ... ok
    t/db-recno.t .. ok
    t/pod.t ....... ok
    All tests successful.
    Files=4, Tests=568, 4 wallclock secs ( 0.13 usr 0.09 sys + 0.94 cusr 1.48 csys = 2.64 CPU)
    Result: PASS
    > make install
    Files found in blib/arch: installing files in blib/lib into architecture dependent library tree
    Installing /home/pablo/localperl/locallib/lib/perl5/i686-linux/auto/DB_File/DB_File.so
    Installing /home/pablo/localperl/locallib/lib/perl5/i686-linux/auto/DB_File/DB_File.bs
    Installing /home/pablo/localperl/locallib/lib/perl5/i686-linux/DB_File.pm
    Installing /home/pablo/localperl/locallib/lib/perl5/i686-linux/auto/DB_File/autosplit.ix
    Installing /home/pablo/localperl/locallib/man/man3/DB_File.3
    Appending installation info to /home/pablo/localperl/locallib/lib/perl5/i686-linux/perllocal.pod


    FIXED!

    installing GraphViz from perl CPAN problem

    Just if someone else get caught by this problem:
    I was trying to install GrapViz.pm.


    First obviously it was failing because I didn't have GraphViz installed. Easy solved with:


    sudo aptitude install graphviz graphviz-dev graphviz-doc libgraphviz-dev graphviz-cairo


    But then when I tried again it was not working:


    cpan> install GraphViz

    GraphViz-2.04/MANIFEST
    '/home/pablo/localperl/bin/perl Makefile.PL' returned status 512, won't make
    Running make test
    Make had some problems, won't test
    Running make install
    Make had some problems, won't install



    So I went to the dir where GV was unpacked and tried to Make it by hand:


    pablo@pmg-linux:~/.cpan/build/GraphViz-2.04-HQxvwp$ perl Makefile.PL
    Scalar value @ENV{PATH} better written as $ENV{PATH} at Makefile.PL line 37.
    Scalar value @ENV{PATH} better written as $ENV{PATH} at Makefile.PL line 40.
    Looking for dot... found it at /usr/bin/dot
    Checking if your kit is complete...
    Looks good
    Warning: prerequisite IPC::Run 0.6 not found.
    Writing Makefile for GraphViz


    OK, this explain it all: I need IPC::Run but it was not show in CPAN

    After Intalling IPC::Run, deleting the GraphViz directory in the build dir (CPAN> clean GraphViz does not work) I tried to install again from CPAN but failed again with the same error that before.

    I went to the extracted GraphViz dir and intalled manually and all was OK.


    > perl Makefile.PL
    > make
    > make test
    PERL_DL_NONLAZY=1 /home/pablo/localperl/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
    t/dumper.t .. ok
    t/foo.t ..... ok
    t/pod.t ..... ok
    t/simple.t .. ok
    All tests successful.
    Files=4, Tests=71, 1 wallclock secs ( 0.04 usr 0.06 sys + 0.42 cusr 0.58 csys = 1.10 CPU)
    Result: PASS
    > make install



    So I don't know why the second time CPAN installation failed, but now it works after the manual install.

    How to know your debian/ubuntu version and architecture

    Which Ubuntu version do you have?

    $ cat /etc/issue
    Ubuntu 9.04


    Which debia?

    $ cat /etc/debian_version
    5.0


    Take all the info of your linux installation:

    In a 32 bits:
    $ uname -a
    Linux pmg-linux 2.6.28-18-generic #60-Ubuntu SMP Fri Mar 12 04:40:52 UTC 2010 i686 GNU/Linux


    If your architecture is 64 bits you should see the "x86_64"

    $ uname -a
    Linux pmg64_linux 2.6.26-2-amd64 #1 SMP Thu Nov 5 02:23:12 UTC 2009 x86_64 GNU/Linux


    Another way of taking info:

    $ cat /proc/version
    Linux version 2.6.28-18-generic (buildd@rothera) (gcc version 4.3.3 (Ubuntu 4.3.3-5ubuntu4) ) #60-Ubuntu SMP Fri Mar 12 04:40:52 UTC 2010

    Wednesday 24 March 2010

    why is not possible to edit and reply to the comments in blogger??!!

    I am having second thoughts about using blogger. I think that I will come back to wordpress where the edition tool is nicer and I can reply comments (they become nested), and I can edit a comment if I do a mistake.

    html perl onliners

    perl onlines html
    http://www.catonmat.net/blog/perl-one-liners-explained-part-five/
    65. URL-escape a string.

    perl -MURI::Escape -le 'print uri_escape($string)'

    You’ll need to install the URI::Escape module as it doesn’t come with Perl. The module exports two functions - uri_escape and uri_unescape. The first one does URL-escaping (sometimes also referred to as URL encoding), and the other does URL-unescaping (URL decoding).

    66. URL-unescape a string.

    perl -MURI::Escape -le 'print uri_unescape($string)'

    This one-liner uses the uri_unescape function from URI::Escape module to do URL-unescaping.

    67. HTML-encode a string.

    perl -MHTML::Entities -le 'print encode_entities($string)'

    This one-liner uses the encode_entities function from HTML::Entities module. This function encodes HTML entities. For example, < and > get turned into < and >.

    68. HTML-decode a string.

    perl -MHTML::Entities -le 'print decode_entities($string)'

    This one-liner uses the decode_entities function from HTML::Entities module.

    More links
    ============

    perl unicode: combined vs full unicode graphemes


    http://www.effectiveperlprogramming.com/blog/102


    -----
    use charnames ':full';

    my $string =
    "\N{LATIN SMALL LETTER A WITH DIAERESIS}"
    . "\N{LATIN SMALL LETTER A}"
    . "\N{COMBINING DIAERESIS}"
    ;
    ää
    ------
    my (@g) = $string =~ /(.)/g;

    say scalar(@g); # 3
    ä a¨
    -----
    my (@g) = $string =~ /(\X)/g;

    say scalar(@g); # 2

    ä ä

    ------

    my $precomposed =
    "\N{LATIN SMALL LETTER A WITH DIAERESIS}";

    my $combined =
    "\N{LATIN SMALL LETTER A}" .
    "\N{COMBINING DIAERESIS}";
    ------

    if ($precomposed eq $combined) {
    say 'equal';
    } else {
    say 'unequal';
    }
    unequal
    ------
    use Unicode::Normalize;

    my $postcomposed = NFC($precomposed);

    if ($precomposed eq $postcomposed) {
    say 'equal';
    } else {
    say 'unequal';
    }
    equal


    ------
    use open IO => ':utf8';

    use open OUT => ':shiftjis';

    use open IN => ':cp1251';

    open my ($ofh), '>:utf8', $filename;

    open my ($ifh), '<:encoding(iso-8859-1)', $filename;

    ------

    But what about command line arguments?
    use I18N::Langinfo qw(langinfo CODESET);
    use Encode qw(decode);

    my $codeset = langinfo(CODESET);

    @ARGV = map { decode $codeset, $_ } @ARGV;
    ------


    ------

    Basic exception handling in Perl

    Basic exception handling in Perl

    Basic try catch pattern in perl
    http://www.perlfoundation.org/perl5/index.cgi?exception_handling

    [copy-paste]
    The most basic way to handle exceptions in Perl is to use an eval BLOCK and have $@ transmit the error.
    eval {                          # try
        ...run the code here....
        1;
    } or do {                       # catch
        ...handle the error using $@...
    };

    Because the eval block ends with a true statement, it will always return true if it succeeds and false otherwise.
    $@ can be a simple string, reference or an object, and is "thrown" by die

    Dangers of using $@

    The more common, but subtly flawed, idiom is to check $@ to see if the eval failed.
    # FLAWED!
    eval {                           # try
        ...run the code here...
    };
    if( $@ ) {                       # catch
        ...handle the error using $@...
    }

    This method is essentially non-atomic and has proven finicky. The problem lies with using $@. As it is global and there are many things which can reset it, either intentionally or otherwise, between the eval block failing and when it is checked.
    =====
    Other blog entry about error handling

    http://perliscope.blogspot.com/2009/11/perl-error-handling.html


    =====
    [update]
    CPAN modules

    Try::Tiny # simple and functinal
    TryCatch # has more dependencies but is nicer than Try::Tiny

    Error
    Exception::Class
    Other modules are useful for checking exception handling during testing:


    ========

    == EDITED 2010-10-15==
    See new discusion in perlmonks

     Best Practices for Exception Handling

          Some reasons I like exceptions:
          1. Robustness. I can forget to check for an returned error value. I cannot forget to check for an exception.
          2. Brevity. I prefer:




            $o->foo->bar->fribble->ni
            to




            $o->foo or return(ERROR_FOO); $o->bar or return(ERROR_BAR); $o->fribble or return(ERROR_FRIBBLE); $o->ni or return(ERROR_NI);
          3. Clarity. With exception based code the "normal" flow of control is more explicit because it is not obscured by error handling code. I think that the first of the two code examples above shows the intent of the code more directly than the second does.
          4. Separation of concerns. The error condition and the error handler are different ideas.




            • You may want an error to be handled in different ways depending on the context.
            • You may also not know how the error should be handled at the point it occurs.
            • You may not know how the error should be handled at the time you write the code.
            With the return-error-code style you end up having to either:




            • propogate error conditions to where the decision on how they should be handled can be made.
            • propogating error handlers down to where the errors may occur
            Both options rapidly become messy if there are many levels of code between the error condition and the error handler.
          5. No confusion between return values and error conditions.
          There are probably some more ;-)
    Re: Re: Best Practices for Exception Handling
    by IlyaM (Parson) on Jan 30, 2003 at 09:54 UTC The fact is that when you write code in modular fashion one part of your system cannot always know how to handle errors itself. In such cases the only thing you can do is pass error somewhere else and there are in general two ways to do it: exceptions and return codes. And exceptions is just a more robust way to do it.
    Example: say you are implementing business logic for your application which has multiple frontends (CLI, web and GUI). This part of your application encounters an error (let say a database connection error). What should it do? Print HTML page with error? Produce plain text formated error message for CLI? Write something in the log? No, it is not responsiblity of this part of your system to do these things, it is responsiblity of the frontend part to handle this error. So you just raise an exception and let the frontend to handle it.

    Do you agree that the logic responsible for asking users for a better input belongs to the user interface part and it is not a part of the business logic? I.e. business logic layer have to callback user interface part when it tries to do the error recovery. So you still have to pass control to the callee to do the error recovery that business logic part cannot do on its own as if you were using exception or return codes style of error handling. To me it looks that the error recovery mechanism is essantially the same in both cases. The only difference is added complexity of callback approach. Let's plot a couple of diagrams. Traditional approach (exceptions or return codes) for case when the business logic part bails with error:
    UserInterface BusinessLogic | user input | |------------------------------>| | do some action | |<----------failure-------------| | handle the error | |
    If at the last point the user interface part can handle the error it can either ask the business logic part to redo the action or if this error is unrecoverable print diagnostic error or do something else. Now callback approach:
    UserInterface BusinessLogic UserInte +rface | user input | |------------------------------>| | do some action | |----------failure------------->| | handle th +e error | |
    This diagram clearly show two problems:
    1. This design adds additional requirement on reentrability for at least the user interface and probably for other parts of the system if the error recovery callback calls them.
    2. If error recovery callback can handle the error then program flow is clear. It returns the control to the business logic part which in its turn returns the control to the callee, i.e. back to the user interface part. But what about another case when it cannot handle the error? You still have to return the control back using either exceptions or return codes! Why then bother with callbacks at all?

    Personally I think the following little trick/modification makes for cleaner code... (and I think that raise_error makes more sense if it contains the error message returned...)
    sub bar { my( $self, @args )= @_; eval { $self->method( @args ); 1} or $self->raise_error( $@, @_ ) and return undef; }
    If you can contrive to make raise_error() return undef you can make it even cleaner
    sub bar { my( $self, @args )= @_; eval { $self->method( @args ); 1} or return $self->raise_error( $@, @_ );
    }