Schrift
[thread]8576[/thread]

next LABEL in Subroutinen: gibt es feinere Lösungswege?

Leser: 1


<< >> 10 Einträge, 1 Seite
bloonix
 2006-12-13 15:17
#72503 #72503
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
Hallo Leute,

für folgendes Codebeispiel suche ich eine andere Lösung.

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
MYLOOP: while ( 1 ) {

  open my $fh1, '<', "$file1" or do {
     print STDERR "unable to open $file1: $!\n";
     print STDERR "sleep for 3 seconds\n";
     sleep 3;
     print STDERR "wakeup\n";
     next MYLOOP;
  };

  # irgendeine Verarbeitung
  close $fh1;

  open my $fh2, '<', "$file2" or do {
     print STDERR "unable to open $file2: $!\n";
     print STDERR "sleep for 3 seconds\n";
     sleep 3;
     print STDERR "wakeup\n";
     next MYLOOP;
  };

  # irgendeine Verarbeitung
  close $fh2;

  open my $fh3, '<', "$file3" or do {
     print STDERR "unable to open $file3: $!\n";
     print STDERR "sleep for 3 seconds\n";
     sleep 3;
     print STDERR "wakeup\n";
     next MYLOOP;
  };

  # irgendeine Verarbeitung
  close $fh3;

}


Was mir hier nicht passt ist die do { ... } Anweisung, sobald etwas in
dem Loop fehl schlägt. Ich würde das gerne mit einer Subroutine erledigen,
aber das scheint wohl deprecated zu sein.

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
MYLOOP: while ( 1 ) {

  open my $fh1, '<', "$file1" or foobar($file1);
  # irgendeine Verarbeitung
  close $fh1;

  open my $fh2, '<', "$file2" or foobar($file2);
  # irgendeine Verarbeitung
  close $fh2;

  open my $fh3, '<', "$file3" or foobar($file3);
  # irgendeine Verarbeitung
  close $fh3;

}

sub foobar {
  my $file = shift;
  print STDERR "unable to open $file: $!\n";
  print STDERR "sleep for 3 seconds\n";
  sleep 3;
  print STDERR "wakeup\n";

  {
     no warnings "exiting";
     next MYLOOP;
  }
}


Gibt es vielleicht auch noch andere Lösungswege für mich?

Für ein paar Tipps wäre ich dankbar.

Viele Grüße,
opi
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
nepos
 2006-12-13 15:26
#72504 #72504
User since
2005-08-17
1420 Artikel
BenutzerIn
[Homepage] [default_avatar]
Warum nicht so:
Code (perl): (dl )
unless(open (my $fh1, '<', "$file1")) { ... Fehlerbehandlung ...}
renee
 2006-12-13 15:28
#72505 #72505
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Ungetestet (nur mal so ne Überlegung):
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
MYLOOP: while ( 1 ) {

open my $fh1, '<', "$file1" or foobar($file1) and next;
# irgendeine Verarbeitung
close $fh1;

open my $fh2, '<', "$file2" or foobar($file2) and next;
# irgendeine Verarbeitung
close $fh2;

open my $fh3, '<', "$file3" or foobar($file3) and next;
# irgendeine Verarbeitung
close $fh3;

}

sub foobar {
my $file = shift;
print STDERR "unable to open $file: $!\n";
print STDERR "sleep for 3 seconds\n";
sleep 3;
print STDERR "wakeup\n";
}
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
renee
 2006-12-13 15:30
#72506 #72506
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
@nepos: das löst nicht das eigentliche Problem...

Zur Erklärung:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/perl

use strict;
use warnings;

MYLOOP: for(0..10){
$_ % 2 or test();
print $_,"\n";
}

sub test{
print "not % 2\n";
next MYLOOP;
}


und auch

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/perl

use strict;
use warnings;

MYLOOP: for(0..10){
unless($_ % 2){test()};
print $_,"\n";
}

sub test{
print "not % 2\n";
next MYLOOP;
}


Ergibt:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
~/entwicklung 10> perl modulo.pl 
not % 2
Exiting subroutine via next at modulo.pl line 13.
1
not % 2
Exiting subroutine via next at modulo.pl line 13.
3
not % 2
Exiting subroutine via next at modulo.pl line 13.
5
not % 2
Exiting subroutine via next at modulo.pl line 13.
7
not % 2
Exiting subroutine via next at modulo.pl line 13.
9
not % 2
Exiting subroutine via next at modulo.pl line 13.


Natürlich kannst Du in dem unless-Block immer das gleiche machen, aber wozu gibt's denn subs ? ;)\n\n

<!--EDIT|renee|1166016757-->
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
bloonix
 2006-12-13 15:57
#72507 #72507
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
[quote=nepos,13.12.2006, 14:26]Warum nicht so:
Code (perl): (dl )
unless(open (my $fh1, '<', "$file1")) { ... Fehlerbehandlung ...}
[/quote]
Das wäre das gleiche... was in do { ... } steht, würde ebenso in
unless () { ... } stehen.
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
bloonix
 2006-12-13 16:09
#72508 #72508
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
[quote=renee,13.12.2006, 14:28]Ungetestet (nur mal so ne Überlegung):

Code: (dl )
1
2
3
4
5
MYLOOP: while ( 1 ) {

 open my $fh1, '<', "$file1" or foobar($file1) and next;
 # irgendeine Verarbeitung
 close $fh1;}
[/quote]
Die Überlegung ist garnicht mal so schlecht und klappt auch!
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
bloonix
 2006-12-13 16:18
#72509 #72509
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
Aber ich habe nicht weit genug gedacht...

Hier ein Stück Originalcode:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$socket->connect() or do {
  my $errstr = $socket->errstr();
  $logger->write("unable to connect to $server:$service ($errstr)");
  $socket->disconnect();
  sleep $recon;
  next ENDLESS;
};

$logger->write("connect to $server:$service successful");

$socket->send($auth) or do {
  my $errstr = $socket->errstr();
  $logger->write("unable to send client data to $server:$service ($errstr)");
  $socket->disconnect();
  sleep $recon;
  next ENDLESS;
};


Da sind natürlich die ganzen Objekte, die man natürlich ungern global
in der Subroutine anspricht. Und woher soll die Subroutine bei Übergabe
von Argumenten wissen, wie die Methoden heissen... zum Beispiel
disconnect(), write() ...\n\n

<!--EDIT|opi|1166019559-->
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
renee
 2006-12-13 16:26
#72510 #72510
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
my %messages = (
1 => 'cannot connect to server',
2 => 'unable to send data',);

$socket->connect() or logging($socket,$logger,$messages{1})
and next;
sub logging{
my ($sock,$log,$msg) = @_;
$log->write($msg . $sock->errstr());
$sock->disconnect;
}
\n\n

<!--EDIT|renee|1166020053-->
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
renee
 2006-12-13 16:32
#72511 #72511
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Oder wenn Du Methoden generisch aufrufen willst:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/perl

use strict;
use warnings;
use CGI;

MYLOOP: for(0..10){
$_ % 2 or test(CGI->new, 'header') and next;
print $_,"\n";
}

sub test{
my ($obj,$method) = @_;
no strict 'refs';
print $obj->$method();
}


Ausgabe:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
~/entwicklung 25> perl modulo.pl 
Content-Type: text/html; charset=ISO-8859-1

1
Content-Type: text/html; charset=ISO-8859-1

3
Content-Type: text/html; charset=ISO-8859-1

5
Content-Type: text/html; charset=ISO-8859-1

7
Content-Type: text/html; charset=ISO-8859-1

9
Content-Type: text/html; charset=ISO-8859-1
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
bloonix
 2006-12-13 19:54
#72512 #72512
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
[quote=renee,13.12.2006, 15:26]
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
my %messages = (
 1 => 'cannot connect to server',
 2 => 'unable to send data',);

$socket->connect() or logging($socket,$logger,$messages{1})
                   and next;
sub logging{
   my ($sock,$log,$msg) = @_;
   $log->write($msg . $sock->errstr());
   $sock->disconnect;
}
[/quote]
Das ist garnicht so schlecht und sollte soweit reichen.

Was mir hier auch ganz gut gefällt sind die Error-Codes, die man vorher
definieren kann. Sowas habe ich bei größeren Projekten ganz gerne
eingesetzt, weil es die Suche in Skripts erleichtert, als nach Texten zu
suchen. Das Problem ist nur, dass man die Codes nicht durcheinander
bringen darf, da man ansonsten an den falschen Stellen nach Fehlern
sucht, obwohl sie an einer ganz anderen Stelle auftauchen. Sowas ist zum
verfluchen. Ich spreche aus bitterer Erfahrung. :p\n\n

<!--EDIT|opi|1166032599-->
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
<< >> 10 Einträge, 1 Seite



View all threads created 2006-12-13 15:17.