arunvelusamy has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks,
I am doing oo perl. I have a reference to a annonymous subroutine in a package "DbManager", and i want to call it in another package "addbook"(The reference is to be passed to HTML::pager). When i execute it, throws error. Can u help me. FYI rowCount works fine.

DbManager package:
my $get_db_data = sub { my ($offset,$per_page)=@_; my (@return_array, @data); connectDb() if(!$dbHandle); my $stmtHandle = $dbHandle->prepare("select id,name,address,email, +phone from ADDRESSBOOK limit $offset, $per_page"); $stmtHandle->execute(); while(@data = $stmtHandle->fetchrow_array()) { push(@return_array, [@data]); } $stmtHandle->finish(); $dbHandle->disconnect(); return \@return_array; };
addbook package:
my $pager = HTML::Pager->new(query=>$query, get_data_callback=>DbManager::get_db_data, rows=>DbManager->rowCount, page_size=>5, cell_space_color=>'#000000', cell_bacground_color=>'#ffffff', debug=>1 );
Thanks in advance..... arunvelusamy

Replies are listed 'Best First'.
Re: [ooperl] calling reference to a annonymous sub
by Fang (Pilgrim) on Nov 07, 2005 at 08:40 UTC

    From what I understand about packages, namespaces and scope, you're missing two things:

    • $get_data_sub should be declared with our, as in:
      % perl -wle'package foo; our $bar = "10"; package main; print $foo::ba +r' 10
      Trying the same with my will result in a warning when you try to print an uninitialized variable.

    • in your addbook package, add the correct sigil to the variable, i.e. $DbManager::get_db_data

    Hope this helps.

      Yes, and elaborating that so it works with an anonymous sub:
      #!/usr/bin/perl #anonysub.pl #use strict; #use warnings; package foo; our $bar = "10\n"; our $anonysub = sub { print "10\n"}; package main; print $foo::bar; &$foo::anonysub(); #before BUU's comment $foo::anonysub->(); #after BUU's comment
      outputs:
      10 10
      (The syntax of the final line took me a bit of trial and error to get it right!)

      UPDATE: added another way to do it as BUU suggests below, which, I agree, is cleaner.

        Just a note, generally it's easier and cleaner to use the ->() syntax to call subroutine references, as in your example:  $foo::sub->().