Anfängerproblem / -frage IO::Select

Hallo liebe Kameltreiber,

auch ich möchte mich programmiersprachentechnisch weiterbilden, und meine Wahl ist auf Perl gefallen. Nach einigen kleinen Übungsscripts habe ich mal einen Echo-Client geschrieben, der von STDIN liest, das Gelesene per UDP an einen Echo-Server schickt und gleichzeitig mittels IO::Select auf die Antwort wartet (nachfolgend der Quelltext). Das Script funktioniert auch, aber mir stellen sich zwei Fragen:

  1. Kann ich STDIN so wie Sockets irgendwie objektorientiert kapseln? Das nackte *STDIN zu übergeben sieht neben dem $recvsock doch irgendwie hässlich aus.

  2. Warum muss ich, wenn auf STDIN Daten vorliegen, diese zuerst zwischenspeichern? Eigentlich sollte ja auch sowas

    $sendsock->send()

funktionieren, aber bei mir klappts merkwürdigerweise nur über den Umweg.

Grübelnde Grüße
Chondron

#!/usr/bin/perl

use strict;
use IO::Select;
use IO::Socket;

my($sendsock, $recvsock, $nachricht, $MAXLEN,$PORTNO);
$MAXLEN=1024;
$PORTNO=4711;

$recvsock = IO::Socket::INET-\>new(Proto =\>'udp', LocalPort =\> '4712') or die "socket: $@";
$sendsock = IO::Socket::INET-\>new(Proto =\>'udp', PeerAddr =\> '127.0.0.1:4711') or die "socket: $@";
my $s = IO::Select-\>new();

$s-\>add(\*STDIN);
$s-\>add($recvsock);

my @readables;

while (@readables = $s-\>can\_read)
{
 foreach my $hready (@readables)
 {
 if ($hready == $recvsock)
 {
 my $msg;
 defined ($recvsock-\>recv($msg, 1024)) or die "recv: $!";
 print $msg;
 }
 if ($hready == \*STDIN)
 {
 my $temp = ;
 chomp $temp;
 defined ($sendsock-\>send($temp)) or die "send: $!";
 }
 }
}
  1. Kann ich STDIN so wie Sockets irgendwie objektorientiert
    kapseln? Das nackte *STDIN zu übergeben sieht neben dem
    $recvsock doch irgendwie hässlich aus.

du könntest IO::Handle benutzen:

use IO::Handle;
my $h = IO::Handle-\>new\_from\_fd(\*STDIN, "r");
  1. Warum muss ich, wenn auf STDIN Daten vorliegen, diese
    zuerst zwischenspeichern? Eigentlich sollte ja auch sowas

$sendsock->send()

funktionieren, aber bei mir klappts merkwürdigerweise nur über
den Umweg.

ein blankes liest STDIN komplett aus, da es im listenkontext
aufgerufen wird. ich habe es jetzt nicht ausprobiert, aber wenn
du ein scalar davor schreibst, sollte es gehn.

Hallo Tina,

super, genau was ich wissen wollte! Dafür ein *
Der Trick mit dem scalar() klappt auch, nur… gibt es eventuell noch eine Möglichkeit, das abschließende „\n“ zu chomp()en ohne auf eine temporäre Variable zurückzugreifen? STDIN selbst ist ja ein rvalue.

Viele Grüße
Chondron

Der Trick mit dem scalar() klappt auch, nur… gibt es
eventuell noch eine Möglichkeit, das abschließende „\n“ zu
chomp()en ohne auf eine temporäre Variable zurückzugreifen?

das geht leider nicht, da chomp() ja nicht die variable selbst
zurückliefert.
wenn du nur die zeile einsparen willst, könntest du

function(do { local $\_ = ; chomp; $\_ });

machen, aber das ist dann schon nicht mehr wirklich hübsch… =)