passing variable to sub - $_='SendMessage'

S

steve

I have two routines, send tcp packet and receive tcp packet.
Rx packet is a Win32:GUI application.

Rx packet passes the packet contents to a subroutine to process the
contents, except the contents once they get to the sub is always
'SendMessage'???

if I put the subroutine in the main part things are OK with using
$buf.

any help would be great

Routines......

Rx-------------------------------
my $readable_handles = new IO::Select();
$readable_handles->add($main_sock);
while (1) {
Win32::GUI::DoEvents();
( my $new_readable) = IO::Select->select($readable_handles, undef,
undef, 0);

foreach my $sock (@$new_readable) {
if ($sock == $main_sock) {
my $new_sock = $sock->accept();
$readable_handles->add($new_sock);
} else {
# It is an ordinary client socket, ready for reading.
my $buf = <$sock>;
if ($buf) {
print "buf - $buf\n"; <<<<<<<<<--------here is correct contents
RxMsg($buf);
} else {
# Client closed socket. We do the same here, and remove
# it from the readable_handles list
$readable_handles->remove($sock);
close($sock);
}
}
}
}
}
sub RxMsg {
print $_ . " here...\r\n";<<<<<<----------- here is 'SendMessage'
my @actions = split(/,/, $_);
print $actions[0] . " there...\r\n";
switch ($actions[0]) {
case 1 {defined(my $win = $Win32::GUI::Loft::window{Rx_Window})
or return(1);
$win->RxTextfield->Append("action 1\r\n");
chomp($actions[1]);
$win->RxTextfield->Append("$actions[1]\r\n");
open ACTION, "< $actions[1]" or die "cant open file : $!";
while (my $line = <ACTION> ) {
$win->RxTextfield->Append("$line\r\n");
}
}
case 2 {defined(my $win =
$Win32::GUI::Loft::window{Rx_Window}) or return(1);
$win->RxTextfield->Append("action 2\r\n");
}
case 3 {defined(my $win =
$Win32::GUI::Loft::window{Rx_Window}) or return(1);
$win->RxTextfield->Append("action 3\r\n");
chomp($actions[1]);
$win->RxTextfield->Append("$actions[1]\r\n");
open ACTION, "< $actions[1]" or die "cant open file : $!";
while (my $line = <ACTION> ) {
$win->RxTextfield->Append("$line\r\n");
}
}
else {defined(my $win = $Win32::GUI::Loft::window{Rx_Window})
or return(1);
$win->RxTextfield->Append("action unknown\r\n");
}
}
return(1);
}
 
B

Ben Morrow

Quoth steve said:
I have two routines, send tcp packet and receive tcp packet.

The usual term in the Perl world for what you are calling 'routines' is
'programs' or 'scripts'. It's not terribly important, it just took me a
minute to work out what you meant.
Rx packet is a Win32:GUI application.

One of the important skills in debugging a program is to reduce it to
the smallest example which still shows the problem. It is considered a
courtesy to do this *before* posting to Usenet, so people can see your
actual problem and not a whole lot of irrelevant code. In this case your
problem can be reduced to

my $buf = 'foo';
print "buf - $buf\n";
RxMsg($buf);

sub RxMsg {
print "\$_ - $_\n";
}

which instead of producing the output

buf - foo
$_ - foo

as you would have expected, produces

buf - foo
$_ -

instead. Your problem is that subroutine arguments are not passed in $_,
they are passed in @_. So if you replace RxMsg above with

sub RxMsg {
print "\$_[0] - $_[0]\n";
}

it will behave as you expect. FWIW, it's usually better to use 'warn'
than 'print' for diagnostic messages, as they go to STDERR and tell you
where they came from.

Some more general comments on your code follow.
my $readable_handles = new IO::Select();
$readable_handles->add($main_sock);
while (1) {

Sort out your indentation. It makes a huge difference to how
comprehensible code is.

sub RxMsg {
print $_ . " here...\r\n";<<<<<<----------- here is 'SendMessage'

Variables will interpolate into strings, removing '.' operators which
just get in the way.

There is no need to print "\r\n" with messages to the user.

print "$_ here...\n";
my @actions = split(/,/, $_);
print $actions[0] . " there...\r\n";
switch ($actions[0]) {

Huh? This is not Perl as I know it... are you using Switch.pm? I would
recommend against it. It can do veeery strange things on occasion.

open ACTION, "< $actions[1]" or die "cant open file : $!";

It's better to use lexical filehandle (filehandles in variables) than
global barewords, for the same reasons as its better to use local than
global variables. It's safer to use the three-arg form of open. It's
probably better to say what you were trying to open if it fails.

open my $ACTION, '<', $actions[1]
or die "can't open '$actions[1]': $!";
while (my $line = <ACTION> ) {
$win->RxTextfield->Append("$line\r\n");
}

You don't really need to do multiple appends here. Something like

''); said:
case 2 {defined(my $win =
$Win32::GUI::Loft::window{Rx_Window}) or return(1);

This piece appears in all the cases. Move it outside the switch (or the
if/elsif/else I would recommend you replace it with).

Ben
 
S

steve

Quoth steve said:
I have two routines, send tcp packet and receive tcp packet.

The usual term in the Perl world for what you are calling 'routines' is
'programs' or 'scripts'. It's not terribly important, it just took me a
minute to work out what you meant.
Rx packet is a Win32:GUI application.

One of the important skills in debugging a program is to reduce it to
the smallest example which still shows the problem. It is considered a
courtesy to do this *before* posting to Usenet, so people can see your
actual problem and not a whole lot of irrelevant code. In this case your
problem can be reduced to

my $buf = 'foo';
print "buf - $buf\n";
RxMsg($buf);

sub RxMsg {
print "\$_ - $_\n";
}

which instead of producing the output

buf - foo
$_ - foo

as you would have expected, produces

buf - foo
$_ -

instead. Your problem is that subroutine arguments are not passed in $_,
they are passed in @_. So if you replace RxMsg above with

sub RxMsg {
print "\$_[0] - $_[0]\n";
}

it will behave as you expect. FWIW, it's usually better to use 'warn'
than 'print' for diagnostic messages, as they go to STDERR and tell you
where they came from.

Some more general comments on your code follow.
my $readable_handles = new IO::Select();
$readable_handles->add($main_sock);
while (1) {

Sort out your indentation. It makes a huge difference to how
comprehensible code is.

sub RxMsg {
print $_ . " here...\r\n";<<<<<<----------- here is 'SendMessage'

Variables will interpolate into strings, removing '.' operators which
just get in the way.

There is no need to print "\r\n" with messages to the user.

print "$_ here...\n";
my @actions = split(/,/, $_);
print $actions[0] . " there...\r\n";
switch ($actions[0]) {

Huh? This is not Perl as I know it... are you using Switch.pm? I would
recommend against it. It can do veeery strange things on occasion.

open ACTION, "< $actions[1]" or die "cant open file : $!";

It's better to use lexical filehandle (filehandles in variables) than
global barewords, for the same reasons as its better to use local than
global variables. It's safer to use the three-arg form of open. It's
probably better to say what you were trying to open if it fails.

open my $ACTION, '<', $actions[1]
or die "can't open '$actions[1]': $!";
while (my $line = <ACTION> ) {
$win->RxTextfield->Append("$line\r\n");
}

You don't really need to do multiple appends here. Something like

''); said:
case 2 {defined(my $win =
$Win32::GUI::Loft::window{Rx_Window}) or return(1);

This piece appears in all the cases. Move it outside the switch (or the
if/elsif/else I would recommend you replace it with).

Ben

Hi Ben,

Many thanks for fast response, I think the $_ / @_ was a 'cant see
wood for the trees' - should have seen that my self.

Your right about reducing problem to min code to help the helpers, I
would have if I'd under stood the issue :-(

Yep, use Switch; working for this case and will replace it if things
go awry with if/elsif/else.

think I got all your points except the ->Append / join one, dont see
how it can be used to replace the 3 appends
case 3 {
$win->RxTextfield->Append("action 3\r\n");
chomp($actions[1]);
$win->RxTextfield->Append("$actions[1]\r\n");
open my $ACTION, '<', $actions[1] or die "cant open '$actions[1]' :
$!";
while (my $line = <$ACTION> ) {
$win->RxTextfield->Append("$line\r\n");
}
}

but that ok got most of your very useful help

many thanks again

steve
 
B

Ben Morrow

[please trim quotations when replying]

Quoth steve said:
think I got all your points except the ->Append / join one, dont see
how it can be used to replace the 3 appends
case 3 {
$win->RxTextfield->Append("action 3\r\n");
chomp($actions[1]);
$win->RxTextfield->Append("$actions[1]\r\n");
open my $ACTION, '<', $actions[1] or die "cant open '$actions[1]' :
$!";
while (my $line = <$ACTION> ) {
$win->RxTextfield->Append("$line\r\n");
}

This 'while' loop will call ->Append multiple times (once for each line
in the file). The replacement I posted avoids that. The two previous
calls to ->Append are still needed, of course.

Ben
 
S

steve

[please trim quotations when replying]

Quoth steve <[email protected]>:


think I got all your points except the ->Append / join one, dont see
how it can be used to replace the 3 appends
case 3 {
$win->RxTextfield->Append("action 3\r\n");
chomp($actions[1]);
$win->RxTextfield->Append("$actions[1]\r\n");
open my $ACTION, '<', $actions[1] or die "cant open '$actions[1]' :
$!";
while (my $line = <$ACTION> ) {
$win->RxTextfield->Append("$line\r\n");
}

This 'while' loop will call ->Append multiple times (once for each line
in the file). The replacement I posted avoids that. The two previous
calls to ->Append are still needed, of course.

Ben

Ah, got you.
but thats what I intended, but I now also see what your suggesting

cheers

steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top