Search code examples
perlmojoliciousmojo

MOJO perl Deprecated warnings


I am learning Mojo, this is my first script and it works fine - that is it does what i want it to do.

use Mojo::UserAgent;
use Mojo::DOM;
use Mojo::Collection;
use strict;
use warnings;

my $ua = Mojo::UserAgent ->new;
my $dom = Mojo::DOM ->new;

$dom = $ua->get('http://lalalala....')->res->dom;

open (my $file_zlec, "> zlc2012.csv") or die "couldn't open file!";
binmode $file_zlec, ":utf8";

for my $zlec($dom->find('table.tbl_zlc')->each){
    print "$i \n"; $i++;

    wypisz($zlec, 'td.tbl_zlc_d1',1);
    print $file_zlec"\n";

}

sub wypisz{ 
    my $ch= $_[0]-> find($_[1])->children;

    if ($_[2]==1){
        my $tekst = $ch->text;
        print $file_zlec "$tekst;";
    }   

    my $href= $ch->map(attr => 'href');
    if (not $href=~/lalala\.pl/g) {$href="www.lalala.pl".$href};
    print $file_zlec "$href;";

}

However, a get a lot of warnings regarding "children", "text" and "attr": 'Mojo::Collection::AOUTOLOAD (..) is DEPRECATED in favor of MOJO::Collection::map at (..)' 'Stringifacation support in Mojo::Collection::AOUTOLOAD (...) is DEPRECATED in favor of Mojo::Collection::join at (..)

I thought i was doing smth wrong, but I followed the example at http://mojocasts.com/e5 EXCACTLY and got the same warnings

use Mojo::UserAgent;

my $ua = Mojo::UserAgent ->new;
print $ua->get('http://mojolicio.us')->res->dom->html->head->title;

My questions are: 1. should i worry? like i said, scripts works fine 2. if ans(1) is no, is there a way to turn this off? i can't see anything in a command line..


Solution

  • Okay it looks like these deprecations have been added recently. For example the AUTOLOAD deprecation was introduced at the end of October this year, and my version of Mojolicious preceded that so I wasn't seeing the messages you were getting. I've now upgraded my installation and understand the problem.

    Unfortunately, the Mojolicious DEPRECATED messages are generated by the Carp module and they don't respond to the no warnings pragma. The only way I know to disable then is to set the warning handler to a null subroutine, like this

    $SIG{__WARN__} == sub {  };
    

    but that is very heavy-handed as it silences all warnings instead of just the nuisance ones you are seeing.

    Since the facility you are using is deprecated, it is likely to be removed from the Mojolicious suite in the near future, so it is best anyway if you learn to adopt the new standard from the outset.

    The message says

    Mojo::DOM::AUTOLOAD (html) is DEPRECATED in favor of Mojo::DOM::children
    

    which means that they would prefer that you used $dom->children('html') instead of just $dom->html. But children returns a Mojo::Collection object, which is a set of nodes, so you need to select the first item of that collection. That turns

    $dom->html->head->title
    

    into the cumbersome

    $dom->children('html')->first->children('head')->first->children('title')->first
    

    so it is far better to use the at method which takes a CSS3 expression, and you can write

    $dom->at('html > head > title')
    

    which is fine, and generates no warnings. Note that it isn't an exact replacement for the children/first chain, as the entire document is being searched for a title node that is a child of a head node that is a child of an html node. But since the only place that this can occur is at the root of the document, the result is identical. Even this can be fixed by using the CSS3 item :root in place of html.

    The complete program would look like this

    use strict;
    use warnings;
    
    use Mojolicious;
    
    my $ua = Mojo::UserAgent->new;
    my $dom = $ua->get('http://mojolicio.us')->res->dom;
    
    print $dom->at('html > head > title')->text;
    

    output

          Mojolicious - Perl real-time web framework