hello all,

i am getting the following error when i am trying to run my 1st Perl script:

[id=0 @ 0] : IP address "3.3.3.3" corresponds to device "core". 
Thread 1 terminated abnormally: Not a CODE reference at ./dev_ithread.pl line 23.
[id=0 @ 1] : IP address "5.5.5.5" corresponds to device "border". 
Thread 2 terminated abnormally: Not a CODE reference at ./dev_ithread.pl line 23.

and here is what i have written so far:

#!/usr/bin/perl

use	strict ;
use	warnings ;
use	diagnostics ;
use	threads ;
use	Config ;

$Config{useithreads} || die("\n---> Please recompile Perl with \<ithreads\> included. \n") ;


# IP parameterization of network elements.
my %device_ip = ( 
			"core" => "3.3.3.3",
			"border" => "5.5.5.5",		
		) ;

# Initialize devices' pool of threads.
my $index = 0 ;
my @device_thread = () ;
while( my ($key, $value) = each %device_ip )	
{ 
	push( @device_thread, threads->new(\&thread_job($key, $device_ip{$key}, $index))->join ) ;	$index = $index+1 ;
}

# Worker thread subroutine.
sub thread_job
{
	my ($device, $ip, $index) = @_ ;

	my $ithread = threads->tid() ;
	print "[id=$ithread @ $index] : IP address \"$ip\" corresponds to device \"$device\". \n" ;
}

i would be thankful, if someone could help me overcome this problem. thank you.

Comments
With code and error message, excellent!

I don't know about threads and my perl is not built for threads but I can illustrate the problem by the following:

#!/usr/bin/perl
use strict;
use warnings;
use 5.010;

#When you follow the sub name with arguments in parentheses
#the sub runs first and returns a scalar value,
#which the backslash makes into a scalar reference.
say ref(\&example(1, 2, 3));#See? We have a SCALAR reference, not a CODE ref

say ref(\&example);#Now we have a CODE reference.

sub example{
    my ($arg1, $arg2, $arg3) = @_; #Do something with arguments, if any
    return 'example sub executed successfully';
}

The threads->new() method (actually threads->create()) accepts a "coderef" which is a reference to a method, and a list of parameters that are passed to the coderef:

threads->new(\&thread_job, $key, $device_ip{$key}, $index)

if you use () after the coderef then perl will a: invoke the method, then b: return a reference to the returned value:

sub code {
    my ($param, $other_param) = @_;
    return $param.$other_param;
}

my $coderef = \&code;
my $noref = \&code("hello ", "world\n");

print "$noref is ". ${$noref};
print "$coderef is " . $coderef->("goodbye ", "baseball\n");

• [barvazon:~] erez $ perl foo
SCALAR(0x8eec818) is hello world
CODE(0x8f076b0) is goodbye baseball

References are a bit tricky to grok at first, but once you wrap your head around references, your perl will automagically leap forward.