みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

PerlでのUseless use...

お世話になります。
真になる演算子が1を、偽になる演算子がundefを返すことを研究しています。

print "3 == 3:【", 3 == 3, "】\n";

であれば、3 = 3が1を返すので

3 = 3:【1】

となります。

print "3 > 4:【", 3 > 4, "】\n";

であれば、3 > 4がundefになるので

3 > 3:【】

になります。

さて、and 演算子を使ったところも見たいと重い、

print "3 == 3 and 3 > 4:【", 3 = 3 and 3 > 4, "】\n";

と書いて実行すると
Useless use of a constant in void context at C:\Perl\perl\showAndTF.pl line 8.
という警告と共に

3 == 3 and 3 > 4:【1

と出力されてしまいます。
これはなぜでしょうか。
よろしくお願いします。

投稿日時 - 2012-09-09 09:39:07

QNo.7688326

すぐに回答ほしいです

質問者が選んだベストアンサー

多分、and の優先順位が , よりも低いせいだと思う。

投稿日時 - 2012-09-09 11:14:49

補足

上のTacosanさんの回答と合わせで納得しました。
http://perldoc.jp/docs/perl/perlop.pod
に演算子の結合順位が出ていますね。

私が書いた式の場合、,よりandの結合順位が低いので、andの前後で式が分断してしまうんですね。

どうもありがとうございました!

投稿日時 - 2012-09-10 11:25:57

お礼

おお、なるほどですね!
ううーん、まだバッチリは分かりませんが、ありがとうございます!

引き続き何かありましたらよろしくお願いします!

投稿日時 - 2012-09-09 14:26:38

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.4

Perl が持っている論理演算子は, もともと (C に由来する) &&, || などのみでした. リストを作る演算子 , はこれらより優先順位が低いので, 例えば
print "3 == 3 && 3 > 4:【", 3 = 3 && 3 > 4, "】\n";

print "3 == 3 && 3 > 4:【", (3 = 3 && 3 > 4), "】\n";
という解釈をします.

ところが, 論理演算子を制御構造として使おうとするとこの動作は不都合です. 例えば, #2 のように「open できなかったら~」というのを表そうと
open my $fh, "<" , $file || die croak("Cannot open $file");
としちゃうと
open my $fh, "<" , ($file || die croak("Cannot open $file"));
を意味するけど, これは明らかに期待した動作じゃない.

で, このようなときのために「演算子 , よりさらに優先順位が低い論理演算子」として and や or などが導入されたんです.

投稿日時 - 2012-09-10 00:37:07

お礼

ありがとうございます!
私は||、&&を使わないでand、orを使っていましたが、優先順位が違うんですね。

投稿日時 - 2012-09-10 11:23:12

ANo.2

>そうではなくて、3 = 3でリストは打ち切られてしまうということですね?
>それがなぜか知りたいのです。

なぜかって・・・演算子とか関数の優先順位を考えましょう

open my $fh, "<" , $file die croak("Cannot open $file");

なんかと同じです.

一般に関数の引数が優先順位が高いのと
引数の終端をどうやってみつけるかという話です


もし,期待通りにしたいのであれば

print "3 == 3 and 3 > 4:【", (3 == 3 and 3 > 4), "】\n";

です.

投稿日時 - 2012-09-09 11:14:29

ANo.1

>真になる演算子が1を、偽になる演算子がundefを返すことを研究しています。

何をやってるのかさっぱりわからんけど・・・
ついでにいうと,Perlのバージョンも明記せんとだめ
5.10.0だとぜんぜん違うエラーになるし
表示もちがうから

Perlの場合
print ってのが
実はリストを受け取る「関数」だということを知ってますか?

>print "3 == 3 and 3 > 4:【", 3 = 3 and 3 > 4, "】\n";

ってのは

print ("3 == 3 and 3 > 4:【", 3 = 3) and 3 > 4, "】\n";

と同じでしょうね.

ついでにいうと,3=3 の段階で,既に問題があるから
Can't modify constant item in scalar assignment
がでるかも

投稿日時 - 2012-09-09 10:01:27

お礼

ご回答ありがとうございます。

すみません。間違えました。
×print "3 == 3 and 3 > 4:【", 3 = 3 and 3 > 4, "】\n";
○print "3 == 3 and 3 > 4:【", 3 == 3 and 3 > 4, "】\n";
です。

おっしゃるとおりprint関数の第一引数に
"3 == 3 and 3 > 4:【"
という文字列を、第二引数に
3 = 3 and 3 > 4
という論理式を、第三引数に
"】\n"
という文字列を渡そうとしています。

結果として

3 == 3 and 3 > 4:【】

という結果を得たいと思っていました。
(【と】の間は偽になるので)

そうではなくて、3 = 3でリストは打ち切られてしまうということですね?
それがなぜか知りたいのです。

Perl は5.8.8です。
よろしくお願いします。

投稿日時 - 2012-09-09 10:36:48

あなたにオススメの質問