• ベストアンサー

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 と出力されてしまいます。 これはなぜでしょうか。 よろしくお願いします。

  • Perl
  • 回答数4
  • ありがとう数3

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

  • ベストアンサー
  • koko_u_u
  • ベストアンサー率18% (216/1139)
回答No.3

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

TYWalker
質問者

お礼

おお、なるほどですね! ううーん、まだバッチリは分かりませんが、ありがとうございます! 引き続き何かありましたらよろしくお願いします!

TYWalker
質問者

補足

上のTacosanさんの回答と合わせで納得しました。 http://perldoc.jp/docs/perl/perlop.pod に演算子の結合順位が出ていますね。 私が書いた式の場合、,よりandの結合順位が低いので、andの前後で式が分断してしまうんですね。 どうもありがとうございました!

その他の回答 (3)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.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 などが導入されたんです.

TYWalker
質問者

お礼

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

  • kabaokaba
  • ベストアンサー率51% (724/1416)
回答No.2

>そうではなくて、3 = 3でリストは打ち切られてしまうということですね? >それがなぜか知りたいのです。 なぜかって・・・演算子とか関数の優先順位を考えましょう open my $fh, "<" , $file die croak("Cannot open $file"); なんかと同じです. 一般に関数の引数が優先順位が高いのと 引数の終端をどうやってみつけるかという話です もし,期待通りにしたいのであれば print "3 == 3 and 3 > 4:【", (3 == 3 and 3 > 4), "】\n"; です.

  • kabaokaba
  • ベストアンサー率51% (724/1416)
回答No.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 がでるかも

TYWalker
質問者

お礼

ご回答ありがとうございます。 すみません。間違えました。 ×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です。 よろしくお願いします。

関連するQ&A

  • Perlで use strict して our変数

    Perl 初心者です。初めて質問します。 test_sub.pl で宣言した変数を test_main.pl から参照したくて悩んでいます。 環境 : WindowsXP / ActivePerl 5.14.2 -------------------- * test_sub.pl -------------------- #!/usr/bin/perl use strict; our $hoge = 'HOGE'; 1; -------------------- * test_main.pl -------------------- #!/usr/bin/perl use strict; require 'test_sub.pl'; print "Content-type: text/html\n\n"; print $hoge; -------------------- これを実行すると、 Global symbol "$hoge" requires explicit package name at C:/public_html/cgi-bin/test_main.pl line 7.\r というエラーが出ます。 require する前に、test_main.pl のほうで our($hoge); と宣言したり 参照する際に print $main::hoge; とパッケージを指定したりすればいけるのですが、 これらをしないとできないものなのでしょうか。 use strict; を書かなければ最初のソースでも動くのですが use strict は書きたい… 継承のようなことをしたいのです。 ちなみに以下試してみたソースです。 -------------------- * test_main.pl -------------------- #!/usr/bin/perl ######################################## # NG use strict; require 'test_sub.pl'; print "Content-type: text/html\n\n"; print $hoge; ######################################## # OK our変数を宣言しておくといける =pod use strict; our ($hoge); require 'test_sub.pl'; print "Content-type: text/html\n\n"; print $hoge; =cut ######################################## # OK 参照する際にパッケージ名を指定すればいける =pod use strict; require 'test_sub.pl'; print "Content-type: text/html\n\n"; print $main::hoge; =cut ######################################## ######################################## # NG =pod use strict; use base qw(test_sub); print "Content-type: text/html\n\n"; print $hoge; =cut ######################################## -------------------- * test_sub.pm -------------------- #!/usr/bin/perl package test_sub; use strict; our $hoge = 'HOGE'; 1; -------------------- NG パタンはどちらも Global symbol "$hoge" requires explicit package name のエラーとなります。 もしご存じの方がいらっしゃいましたら教えてください。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • Perlで参照のクリアの方法

    Perlで参照のクリアで困っているのですが、以下のソースで正しくクリア方法はありますか? use strict; use warnings; use Data::Dumper; sub test { my ($arrayref) = @_; $$arrayref[2]{'A'} = 'aaaaa'; #$$arrayref = (); # Not a SCALAR reference at test_0042.pl line 10. $arrayref = (); #←クリアしているが、Dumperするとクリアされていない } my @A = (); print Dumper(@A); print "\n"; test(\@A); print Dumper(@A); print "\n"; exit; __END__ $VAR1 = undef; $VAR2 = undef; $VAR3 = { 'A' => 'aaaaa' };

    • ベストアンサー
    • Perl
  • perlの論理演算子の「and」と「&&」の違い

    perlの論理演算子の「and」と「&&」の違いは、 「弱い結合」と「強い結合」とかで説明されている のを見かけますが、これは、 「短絡評価」(左側が偽だと右側が実行されない)と 「短絡評価でない」(左側の真偽に関係なく右側が実行される) のと同じ意味になるのでしょうか。 例えば、 sub x {  print "sub x\n";  return 0; } sub y {  print "sub y\n";  return 1; } の2つのサブルーチンがある場合に、 (1) if(&x==1 and &y==1){    print '真',"\n";   } else {    print '偽',"\n";   } (2) if(&x==1 && &y==1){    print '真',"\n";   } else {    print '偽',"\n";   } を、実行した場合、サブルーチンyは、 (1)では実行されず、(2)では実行される という理解で正しいでしょうか。 (実際にはどちらも実行されていないようなのですが)

    • ベストアンサー
    • Perl
  • perl2exeでuse encodingが使えない

    下記のようなスクリプトを作成しました。 スクリプト名は test_kanji.pl ---------------- use encoding("shift-jis"); print "表現\n"; ----------------- 上記を実行すると、正しく”表現”の文字が表示されます。 これをperl2exeで実行形式に変換すると 下記のエラーが表示され、期待した結果が得られません。 Converting 'test_kanji.pl' to test_kanji.exe Warning: Can't locate I18N/Langinfo.pm at C:\Perl\lib\encoding.pm line 41 @INC = c:\perl\userlib, C:\Perl\lib, C:\Perl\site\lib, . 又、強引にtest_kanji.exeを実行すると encoding: Unknown encoding 'shift-jis' at C:\Perl\userlib\test_kanji.exe line 1 BEGIN failed--compilation aborted at C:\Perl\userlib\test_kanji.exe line 1. のようなメッセージが表示され、”表現”が表示されません。 perl2exeでuse encodingは使用できないのでしょうか。

  • use strictが効かない (PERL)

    たびたびお世話になっております。 PERL version 5.14.2 をWindows 7 のコマンドプロンプトから起動して使っています。 use strict; と一行目に書くと 宣言されていない変数があれば拒絶されるとのことで #!/usr/bin/perl use strict; use warnings; $a = 10; print "$a\n"; というスクリプトを書きました。が、すんなり動いてしまいます。 use strict; は どうすればうまく効くのでしょうか。 ご指導お願いします。

    • ベストアンサー
    • Perl
  • perlからDBIを使用したpostgresへの接続でエラー

    perlからDBIを使用して、データベースにアクセスしたいと思っていますが、connectで下記のようなエラーが出力され接続できません。 ↓↓↓↓↓↓apacheのエラーログ↓↓↓↓↓↓↓ DBI connect('dbname=[mscdb]','[postgres]',...) failed: FATAL: database "[mscdb]" does not exist at /web/member/cgi-bin/dbitest.pl line 8 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ mscdbがないとエラーが出力されているように思いますが、mscdbは存在します。どういった原因が考えられるでしょうか? プログラムには以下のように記述しています。 #!/usr/bin/perl use DBI; use constant DBNAME => 'DBI:Pg:dbname=[mscdb]'; use constant DBUSER => '[postgres]'; use constant DBPASS => '[××××]'; DBI->connect( DBNAME, DBUSER, DBPASS, { AutoCommit => 0 }); print "Content-Type: text/plain\n\n"; print $DBI::errstr? $_: 'Done'; 環境は以下の通りです。    perl v5.8.2    postgres v8.1.2 vine linux dbd v1.49

    • ベストアンサー
    • Perl
  • Perlバージョン違いと use encoding;

    Perl 5.6とPerl 5.8の両方を使っています。 use encoding 'utf8';を 5.6で使うとエラーになるので バージョンを調べて条件分岐を行おうとしていますが、 use はどこに書いても実行される?ので、エラーが回避できません。 何か良い方法はあるのでしょうか? use encoding 'utf'; $|=1; print "Version=$]\n"; use utf8; if($] >= 5.008001){ print "*** PASS ***\n"; use encoding 'utf8'; }

    • ベストアンサー
    • Perl
  • perl use strict エラーにならない?

    perlの使い方を勉強しているのですが use strict;を記述すると 変数宣言が必要になるということですが 以下のように記述してもエラーになりません。 use strict;を記述すると my $a;がないと$a="Hello";で エラーになるのではないのでしょうか。 ---test.pl---- use strict; $a="Hello"; print $a; -------------- >test.pl Hello > (Windows7, ActivePerl)

    • ベストアンサー
    • Perl
  • セッションがうまくできません

    #!c:/Perl/bin/Perl.exe ------セッションを作成する------- use CGI::Session; $session = new CGI::Session(undef,undef,{Directory=>'/tmp'}); $session->expire('+50s'); $session->param("membername","テスト"); $session->flush(); print "Location: ./test.pl\n\n"; ------セッションを読み込む------- #!c:/Perl/bin/Perl.exe print"Content-type: text/html\n\n"; use CGI; use CGI::Session; $q = new CGI(); $session = CGI::Session->new(undef,$q,{Directory=>'/tmp'}); $params = $session->param_hashref(); print$params->{"message"}; $session->flush(); 何もブラウザに表示がされません、どこが間違ってるのでしょうか?

  • perl 5.8.8 日本語マッチ

    perl5.8.8を使っています。 日本語にマッチする正規表現を書きたいのですが、どうしてもマッチしません。 例えば、以下のファイルtest.txtから「さしすせそ」だけを抽出し、表示させたいです。 ---------test.txt-------------------------------- あいうえお かきくけこ さしすせそ たちつてと -------------------------------------------------- ----------test.pl-------------------------------- use strict; use warnings; open(FILE, 'test.txt') or die "$!"; my @file = <FILE>; close(FILE); foreach my $line (@file){ if($line =~ /^さ/){ print "$line\n"; } } ------------------------------------------------ このtest.plを実行しても「さしすせそ」を抽出することが できません。 どうしたらよいのでしょうか? 自宅の新しいバージョンのperlだとできるのですが 会社のperlは5.8.8で顧客環境でもあるのでバージョンアップも できません。 すみませんが、よろしくお願いいたします。

    • ベストアンサー
    • Perl

専門家に質問してみよう