passing variable to sub - $_="SendMessage"
passing variable to sub - $_="SendMessage"
am 12.09.2007 22:39:14 von 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 = ) {
$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 = ) {
$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);
}
Re: passing variable to sub - $_="SendMessage"
am 12.09.2007 23:02:00 von Ben Morrow
Quoth steve :
> 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 = ) {
> $win->RxTextfield->Append("$line\r\n");
> }
You don't really need to do multiple appends here. Something like
$win->RxTextfield->Append(join "\r\n", <$ACTION>, '');
is simpler.
> 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
Re: passing variable to sub - $_="SendMessage"
am 13.09.2007 00:02:15 von Steve
On Sep 12, 10:02 pm, Ben Morrow wrote:
> Quoth steve :
>
> > 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 = ) {
> > $win->RxTextfield->Append("$line\r\n");
> > }
>
> You don't really need to do multiple appends here. Something like
>
> $win->RxTextfield->Append(join "\r\n", <$ACTION>, '');
>
> is simpler.
>
> > 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
Re: passing variable to sub - $_="SendMessage"
am 13.09.2007 01:52:09 von Ben Morrow
[please trim quotations when replying]
Quoth steve :
>
> 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
Re: passing variable to sub - $_="SendMessage"
am 13.09.2007 21:28:17 von Steve
On Sep 13, 12:52 am, Ben Morrow wrote:
> [please trim quotations when replying]
>
> Quoth steve :
>
>
>
> > 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