LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   odd number of elements in hash (https://www.linuxquestions.org/questions/programming-9/odd-number-of-elements-in-hash-4175437458/)

bradvan 11-16-2012 12:07 PM

odd number of elements in hash
 
I'm trying to debug some perl code written by someone else. It has a line:
Code:

Daemon::Generic->newdaemon(
  progname    => 'mycach',
  configfile  => '/ekb/mycach.conf',
  pidfile    => '/var/run/mycach.pid'
);

When run, I get:
Code:

Odd number of elements in hash assignment at /usr/local/share/perl5/Daemon/Generic.pm line 22.
Line 22 is:
Code:

my (%args) = @_;
Run under debug it shows:
Code:

Daemon::Generic::newdaemon('Daemon::Generic', 'progname', 'mycach', 'configfile', '/ekb/mycach.conf', 'pidfile', '/var/run/mycach.pid')
which seems to show 'Daemon::Generic' is thrown in there with no element for some reason. The system has Daemon::Generic 0.82 installed. Anyone have some suggestions?

Thanks!

markush 11-16-2012 01:38 PM

Hi,

it seems that you have to use an even number of arguments to the "constructor" function. Namely pairs of key and value, look here http://perldesignpatterns.com/?NamedArguments
Quote:

my (%args) = @_;
means to use a hash for the parameters.

An explanation of the module is here at cpan http://search.cpan.org/dist/Daemon-G...E_USAGE_OUTPUT

Markus

Sergei Steshenko 11-16-2012 10:16 PM

Quote:

Originally Posted by bradvan (Post 4830926)
I'm trying to debug some perl code written by someone else. It has a line:
Code:

Daemon::Generic->newdaemon(
  progname    => 'mycach',
  configfile  => '/ekb/mycach.conf',
  pidfile    => '/var/run/mycach.pid'
);

When run, I get:
Code:

Odd number of elements in hash assignment at /usr/local/share/perl5/Daemon/Generic.pm line 22.
Line 22 is:
Code:

my (%args) = @_;
Run under debug it shows:
Code:

Daemon::Generic::newdaemon('Daemon::Generic', 'progname', 'mycach', 'configfile', '/ekb/mycach.conf', 'pidfile', '/var/run/mycach.pid')
which seems to show 'Daemon::Generic' is thrown in there with no element for some reason. The system has Daemon::Generic 0.82 installed. Anyone have some suggestions?

Thanks!

I think you should write

Code:

my %args = @_;
.

markush 11-17-2012 03:06 AM

Quote:

Originally Posted by Sergei Steshenko (Post 4831150)
I think you should write

Code:

my %args = @_;
.

:doh: I was missing this when I wrote my above reply. So the problem here is that the parenthesis put the hash %args into a scalar context which makes no sense for Perl.

Markus

bradvan 11-17-2012 05:38 AM

Ah, good catch! That means there must be an error in the CPAN module. Thanks!

bradvan 11-19-2012 07:59 AM

Rats, that wasn't the problem. Adding or removing parenthesis doesn't make a difference. The problem seems to be when the call is made:
Code:

Daemon::Generic->newdaemon (
  progname    => 'mycach',
  configfile  => '/ekb/mycach.conf',
  pidfile    => '/var/run/mycach.pid'
);

perl is passing:
Code:

('Daemon::Generic', 'progname', 'mycach', 'configfile', 'ekb/mycach.conf', 'pidfile', '/var/run/mycach.pid')
and not
Code:

('progname', 'mycach', 'configfile', 'ekb/mycach.conf', 'pidfile', '/var/run/mycach.pid')
Notice the 'Daemon::Generic' is at the head of the list and thus makes an odd number. Any ideas on why 'Daemon::Generic' is included and how to get rid of it?

Regards,

Brad

bradvan 11-19-2012 08:21 AM

I temporarily got around it by adding in the Daemon::Generic sub newdaemon procedure (before the my (%args) line:
Code:

if (($#_ + 1) % 2) {
  shift(@_);
}

which makes it work. I'd still like to find out why the script is adding the 'Daemon::Generic' to the call if anyone knows.

Regards,

Brad V

Sergei Steshenko 11-19-2012 01:01 PM

Quote:

Originally Posted by bradvan (Post 4832575)
Rats, that wasn't the problem. Adding or removing parenthesis doesn't make a difference. The problem seems to be when the call is made:
Code:

Daemon::Generic->newdaemon (
  progname    => 'mycach',
  configfile  => '/ekb/mycach.conf',
  pidfile    => '/var/run/mycach.pid'
);

perl is passing:
Code:

('Daemon::Generic', 'progname', 'mycach', 'configfile', 'ekb/mycach.conf', 'pidfile', '/var/run/mycach.pid')
and not
Code:

('progname', 'mycach', 'configfile', 'ekb/mycach.conf', 'pidfile', '/var/run/mycach.pid')
Notice the 'Daemon::Generic' is at the head of the list and thus makes an odd number. Any ideas on why 'Daemon::Generic' is included and how to get rid of it?

Regards,

Brad


Perl is doing "the right thing" (tm).

My point is that the "->" notation prescribes this behavior - this is how Perl OO model works. The idiom is:

Code:

sub foo
  {
  my $self = shift;
  # deal with the rest of args in @_
  # the code doing the job is here
  # methods are called as $self->method_name(...)
  }


If you do not want this behavior, you should use this:
Code:

Daemon::Generic::newdaemon(...)
form of call.

bradvan 11-20-2012 04:50 AM

Ahh, OK, thanks for the education! :) I'll make the change.

Thanks Again!


All times are GMT -5. The time now is 01:13 AM.