2014-09-01 27 views
5

W innych językach chciałbym napisaćDlaczego "x = a lub b" nie działa w Perlu?

testvar = onecondition OR anothercondition; 

mieć testVar być prawdziwe, jeśli którykolwiek z tych warunków jest. Ale w Perlu to nie działa zgodnie z oczekiwaniami.

Chcę sprawdzić warunek, w którym zmienna content jest pusta lub pasuje do konkretnego regex. Mam ten przykładowy program:

my $contents = "abcdefg\n"; 
my $criticalRegEx1 = qr/bcd/; 
my $cond1 = ($contents eq ""); 
my $cond2 = ($contents =~ $criticalRegEx1); 
my $res = $cond1 or $cond2; 
if($res) {print "One or the other is true.\n";} 

Spodziewałbym się, że $ res będzie zawierało "1" lub coś, co okaże się prawdziwe, gdy testowane z if(). Ale zawiera pusty ciąg.

Jak mogę to osiągnąć w Perlu?

+4

Zapoznaj się z [operator tabeli pierwszeństwa] (http: //perldoc.perl.org/perlop.html#Operator-Precedence-and-Associativity). Porównaj 'lub' z '||'. – user2864740

Odpowiedz

19

Put nawiasy wokół wypowiedzi,

my $res = ($cond1 or $cond2); 

lub użyj wyższej operatora pierwszeństwo ||,

my $res = $cond1 || $cond2; 

jako kod jest interpretowany przez Perl jako (my $res = $cond1) or $cond2;, lub dokładniej,

perl -MO=Deparse -e '$res = $cond1 or $cond2;' 
$cond2 unless $res = $cond1; 

Jeśli używasz use warnings; to również ostrzec dotyczące $cond2,

Useless use of a variable in void context 
+5

Co ciekawe, słowo kluczowe "or" zostało dodane do Perla, gdy ludzie narzekali na przeciwny problem. Perl 4 miał tylko '||' i nie 'lub'. – tripleee

+0

Używam ostrzeżeń w moim kodzie i otrzymałem ostrzeżenie. Jednak w prawdziwym kodzie (nie tym kodzie testowym) oświadczenia nie są podzielone tak jak tutaj, więc nigdy nie otrzymałem ostrzeżenia. A powyżej tego nie rozumiałem, co chciało mi powiedzieć :) Dzięki za dokładną odpowiedź. – jackthehipster

+2

@jackthehipster 'use diagnostics;' będzie bardziej opisowy w odniesieniu do ostrzeżenia. –

1

@jackthehipster: Zrobiliście wszystko prawidłowe wystarczy umieścić szelki dla $cond1 or $cond2 jak pokazano poniżej kodu:

my $contents = "abcdefg\n"; 
my $criticalRegEx1 = qr/bcd/; 
my $cond1 = ($contents eq ""); 
my $cond2 = ($contents =~ $criticalRegEx1); 
my $res = ($cond1 or $cond2); 
if($res) {print "One or the other is true.\n";}