• ベストアンサー

短くできないでしょうか

$Print0 = "0.htm"; $Print1 = "1.htm"; $Print2 = "2.htm"; ... $Print199 = "199.htm"; $Print200 = "200.htm"; と200程度変数があったとして sub _Test{ my $Print; if($FORM{CMD} eq '0'){ $Print0; } elsif($FORM{CMD} eq '1'){ $Print = "$Print1"; } elsif($FORM{CMD} eq '2'){ $Print = "$Print2"; } ... elsif($FORM{CMD} eq '199'){ $Print = "$Print199"; } else{ $Print = "$Print200"; } print <<HTML; $Print HTML } 何とか上記のような形で関数の外にある変数を取得する所まで設定出来たのですが、 このようにすると400行近くになる為、もし$FORM{CMD} eq '1'の値を変数に置き換え取得可能な場合ですと、 少ない行で済ませられるんじゃないのかな・・と考えたのですが可能でしょうか。 イメージとしまして 、 $Print$変数 = "$変数.htm"; if($FORM{CMD} eq '$変数'){ $Print$変数; } 上記のような形で取得可能でしたら物凄く短く済ませられそうに感じてしまいます。 先輩方のお知恵をお借りできましたら幸いです。ご教授宜しくお願い致します。

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

  • ベストアンサー
  • root139
  • ベストアンサー率60% (488/809)
回答No.5

私が思いついたのはハッシュを使う方法でした。 %html_path = ( 0 => "0.htm", 1 => "1.htm", 2 => "2.htm",  ・  ・  ・ 200 => "200.htm" ); という感じのハッシュを作って、 sub _Test{ my $Print; if (defined($html_path{$FORM{CMD}})) { # 該当する項目が存在した場合 $Print = $html_path{$FORM{CMD}}; } else { # 該当する項目が存在しない場合 $Print = ""; } print <<HTML; $Print HTML } となります。 ハッシュですので、$FORM{CMD} にどんな値が入っていても実行時エラーにはなりません。 また、%html_path のキーはどんな文字列でもOKです。 例 ------------------------------------------------------ %html_path = ( hoge => "0101.htm", boo => "0202.htm" ); --------------------------------------------------------- キーや値が連番で構成されている場合は、配列と同じ様にループで初期化することもできます。 例 ------------------------------------------------------ %html_path = (); for ($i = 0; $i <= 200; $i++) { $html_path{$i} = $i . '.htm'; } ---------------------------------------------------------

参考URL:
http://www.rfs.jp/sitebuilder/perl/02/05.html
taku0
質問者

お礼

お忙しい中ご掲示頂きまして有難うございました。 当初の予定は短くすませられないか・・でしたが(今回は記載していなかったのですが)その前提としまして200を越える数字以外に1_1や1_1_1などのケースも考えられる状況でしたので、そうなってくるとハッシュを使ってどのようにすれば解決できるのか・・・を他の方からご掲示頂いても私としては中々案を見出せませんでした。 その為、別途スレッドを正規表現についてで立ち上げ、正規表現で解決できないかと思考を変えてみたような状況でしたのです。 今回は何とか正規表現を使って1~200までの数値と1_20や1_1_14などのケースにも対応させる形を作る事ができました。 今回頂きましたご意見そのものは、ハッシュを使う形の一つの実現の仕方として参考にさせて頂きました。 また仰る通り短くすませるという目的で今回私が提示した条件を抜きにすれば200行余分に入る事にはなりますがroot139 様の掲示された方法でも良いかと思います。 ちなみに短くする事の理由ですが、関数にした場合毎回呼び出し毎に200行又は400行近くあればその呼び出し回数に比例して負荷がかかるのではないかと考えた為でした。 正規表現でその問題を回避したとしても逆に効率が落ちるようであれば、200行ないし400行余分になってもそうするべきなのかな・・とは思います。この件については別途スレッドを立ち上げて質問し皆様の意見を伺ってみたいと思います。 有難うございました。

すると、全ての回答が全文表示されます。

その他の回答 (4)

  • moon_night
  • ベストアンサー率32% (598/1831)
回答No.4

私だったら、途中の変数は排除して直接 $num.htm の状態で書き出すのですが。 sub _Test{ print $FORM{CMD} .'.htm'; } または sub _Test{ # 中身が空の場合は排除する if($FORM{CMD} == 0 or $FORM{CMD} ne '') { my $print = $FORM{CMD} .'.htm'; print $print; } }

taku0
質問者

お礼

皆様大変参考になりますアイデアや方法論につきましてご掲示頂きまして有難うございます。 最初にご掲示頂きました方法ですが、 もし、数値が入ってない場合や数値が200以上だった場合はエラーになるようです。 2番目の方法論ですけれども、中身が空の場合については良いのですが、数値が200を越える場合を想定しますと もう一工夫必要に感じてしまいます。 現在は下記のような形で止まっているのですが、文字列検索を行う形で条件分岐できないかと思考中でございます。 my $Print; if($FORM{CMD} eq ''){ $Print = "00.htm"; } else{ $Print = "$FORM{CMD}.htm"; } を my $Print; if($FORM{CMD} =~ /a|b|c|d|e|f/){ $Print = "$FORM{CMD}.htm"; } else{ $Print = "$FORM{CMD}.htm"; } 当初の目的でした簡単にできないか・・・という目標は何とかクリアできました。 沢山の参考アイデア有難うございました。

すると、全ての回答が全文表示されます。
noname#11136
noname#11136
回答No.3

sub _Testのブロックは単純に下のような感じにすればいいと思います。 sub _Test { my $num = $FORM{CMD}; print <<HTML; ${"Print$num"} HTML } でも200程度の変数$Print数字も用意する必要がない気がします。${"Print$num"}の代わりに$num.htmではだめなのかもしれないですけど、"$num.htm"?、eval($num.htm)? CGI?とかやったことがなくて、よくわかりませんが。

taku0
質問者

お礼

お忙しい所ご掲示頂きまして有難うございます。 こちらにご掲示頂きました例ですが my $num = $FORM{CMD}; として ${"Print$num"} で代入する所が「そっか!」と思わされる瞬間でとても為にになりました。 ですが、良く良く考えてみました所、200以上の数値や$FORM{CMD}に値が入っていない場合を想定しますと まだもう一工夫欲しい所でした。 しかし当初の目標を達成できましたので、少し前進できたように感じます。 有難うございました。

すると、全ての回答が全文表示されます。
回答No.2

手っ取り早く、イメージに近いやり方は、evalを使うのが良いかと。 sub _Test{ my $Print; eval "\$Print=\$Print".$FORM{CMD}.";"; ##ここ print <<HTML; $Print HTML }

taku0
質問者

お礼

深夜にもかかわらずご掲示いただきまして有難うございました。 eval構文で代入する方法というのがあったんですね。 先日も別の件で「ほえ~なるほど~」みたいな感じに思わされる瞬間だったのですが、今回も同様にとても参考になる考えでした。 ですが、当初予定していなかった200以上の数値や値が入っていない場合を想定しますと、いささか不安といいますかエラーになるケースも出てきてしまう為、もう少し思考してみたいと思います。 でもおかげさまで当初の問題を解決する事ができましたので一歩前進する事ができました。 有難うございました。また何かのおりにはご掲示頂けましたら幸いです。

すると、全ての回答が全文表示されます。
  • Bonjin
  • ベストアンサー率43% (418/971)
回答No.1

配列を使えばいいんじゃないでしょうか? 下のコードはちゃんと動かしてないので動くかどうかわかりません(笑 イメージだけ感じ取ってください。 // 初期化 @HtmlPages = (); for($i = 0; $i <= 100; $i++){ $HtmlPages[$i] = "$i.html"; } // 判定 for($i = 0; $i <= 100; $i++){ if($FORM{CMD} eq "$i"){ $Print = $HtmlPages[$i]; last; } }

taku0
質問者

お礼

お忙しい中ご掲示頂きまして有難うございます。 配列を使うという考えですね。 問題は$FORM{CMD}に200以上の数値や空だった場合をどうするか・・だと思いました。 工夫すれば出来るかとは存じますが、まだ私の技術や知識レベルでは直ぐに解決案が見出せず今回は一つの参考にさせて頂くに留まりました。 ゆくゆくは色々な構文を使って自由に条件分岐させられるようになれれば・・と思わせられる一瞬でもありました。 このたびは有難うございました。

すると、全ての回答が全文表示されます。

関連するQ&A

  • 変数値に付いて

    数日前からCGIの勉強を始めた素人です。ご教授,よろしくお願いします。 実際のプログラムを見ながらのほうが覚えるだろうと思い、フリーのスクリプトをダウンロードしてきてそれを見ながら勉強しています。 で、つまずきました。 if ($FORM{'action'} eq 'regist') {&regist;} elsif ($FORM('action') eq 'remove') {&remove;} else {&html;} sub html{   if ($FORM{'action'} eq 'remove') { … 1行目で三つに場合分けしているんですよね? で、subはremoveではないとき。 なのにまたその関数の定義の中で、removeがでてくる。 どういうことなのでしょう? 教えてください。 お願いします。   

    • ベストアンサー
    • CGI
  • この意味を教えて下さい。

    よく、CGIを見ていると始めのほうにこのような行があるのですが、 これはどうゆう意味があるのでしょうか? if ($FORM{'mode'} eq 'view') { &view;exit; } elsif ($FORM{'mode'} eq 'delete') { &delete; } elsif ($FORM{'mode'} eq 'input') { &input; } また、「$FORM{'mode'} 」の意味も教えていただきたいのですが・・・。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • CGIROOMさんのデータベース機能について、管理者と連絡取りたい

    CGIROOMさんのデータベース機能について、管理者と連絡取りたい。 また、簡易高機能検索専用データベース ソート版(http://cgiroom.nu/list/database/database2s/)と、database.cgi用 データエディタ(http://cgiroom.nu/list/database/dataedit/index.htm)を併用して利用しているのですが、データファイルの容量が300k以上になると、エラーが表示されてしまうのですが、これを解除する方法をどなたか教えていただけませんか? ソースデータ if($FORM{'cmd'} eq "edit" && $FORM{'line'}){ &error('300k以上あるデータは修正できません') if -s $FILE > 01234567; open(IN,$FILE) || &error('データファイルを開けません'); @data = <IN>; close(IN); if($FORM{'write'}){ &error('行指定が不正です') if $FORM{'line'} =~ /\D/; $data[$FORM{'line'} - 1] = join("\t",@line[1..$#line],"\n"); open(OUT,">".$FILE)|| &error('データファイルを更新できません'); print OUT @data; close(OUT); &msg('更新しました'); } @data = split(/\t/,"\t".$data[$FORM{'line'} - 1]); &error('指定されたデータは存在しません') unless @data; open(HTML,$FORM)||&error('フォームファイルを開けません'); read(HTML,$html,-s HTML); close(HTML); $html =~ s/__(cmd|line)__/$FORM{$1}/g; $html =~ s/__data(\d+)([a-zA-Z]*)__/&tag($data[$1],$2)/eg; &html(\$html); }elsif($FORM{'cmd'} eq "new"){ &error('300k以上あるデータは修正できません') if -s $FILE > 01234567; if($FORM{'write'}){ if($unshift){ open(IN,$FILE) || &error('データファイルを開けません'); @data = <IN>; close(IN); open(OUT,">".$FILE)|| &error('データファイルを更新できません'); print OUT join("\t",@line[1..$#line],"\n"),@data; close(OUT); }else{ open(OUT,">>".$FILE)|| &error('データファイルを更新できません'); print OUT join("\t",@line[1..$#line],"\n"); close(OUT); } &msg('データを追加しました'); } open(HTML,$FORM)||&error('フォームファイルを開けません'); read(HTML,$html,-s HTML); close(HTML); $html =~ s/__cmd__/$FORM{'cmd'}/g; $html =~ s/__data\d+[a-zA-Z]*__//g; &html(\$html); }elsif($FORM{'cmd'} eq "delete" && $FORM{'line'}){ &error('300k以上あるデータは修正できません') if -s $FILE > 01234567; &error('行指定が不正です') if $FORM{'line'} =~ /\D/; open(IN,$FILE) || &error('データファイルを開けません'); @data = <IN>; close(IN); &error('指定されたデータは存在しません') unless $data[$FORM{'line'} - 1]; undef $data[$FORM{'line'} - 1]; open(OUT,">".$FILE)|| &error('データファイルを更新できません'); print OUT @data; close(OUT); &msg('指定されたデータを削除しました'); } どこを修正すればいいのでしょうか?

  • ひとつのCGIファイルに複数のページの動作を管理

    CGI超初心者です。 HTMLファイルにいくつかラジオボタンを設置し、 これとこれを選んだらこのページを開く、 次のページで、 これとこれを選んだらこのページを開く・・・ というような構成でサイトを作っています。 CGIで条件分岐させていますが 書き方が良く分からないので教えてください。 第一ページ用の条件分岐CGIの下に、第二ページ用の条件分岐CGIを書きましたが うまく動いてくれません。 どちらかを削除するとうまく動きます。 ひとつのCGIファイルに、 複数のページの条件分岐をまとめて書くことは出来ないのでしょうか? ページごとに別々のCGIファイルを作成しなければならないですか? 以下具体例です。 ---第一ページ.html--- <form name="q1" action="test.cgi" method="POST" > ・・・ <input type="submit" value="送信する" /> </form> ---第二ページ.html--- <form name="q2" action="test.cgi" method="POST" > ・・・ <input type="submit" value="送信する" /> </form> ---CGI--- #====================下準備====================== if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $str, $ENV{'CONTENT_LENGTH'}); } else { $str = $ENV{'QUERY_STRING'}; } foreach $i (split('&', $str)) { $i =~ tr/+/ /; $i =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg; ($t1, $t2) = split('=', $i); $FORM{"$t1"} = $t2; } #===================変数の設定=================== $q11 = $FORM{'q11'}; $q12 = $FORM{'q12'}; #=================条件分岐_質問1================= if ($q11 eq "q11_a") { print "Location: ./ba1.html\n\n"; } elsif ($q11 eq "q11_c") { print "Location: ./ba2.html\n\n"; } ・ ・ ・ else { print "Location: ./go2.html\n\n"; } #===================変数の設定=================== $q21 = $FORM{'q21'}; $q22 = $FORM{'q22'}; #=================条件分岐_質問2================== if ($q21 eq "q21_a") { print "Location: ./co3.html\n\n"; } elsif ($q22 eq "q22_a") { print "Location: ./ba4.html\n\n"; } ・ ・ ・ else { print "Location: ./go3.html\n\n"; }

    • ベストアンサー
    • CGI
  • PCでは見れるが、携帯(J-SKY)では見れない。

    YY-BOADRを携帯から見るCGIを作成しました。 件名一覧画面はOKなのですが、 件名をクリックしてその内容を表示する画面に行こうとすると PCでは見れるが、携帯(J-SKY)では白い画面が表示されるだけでした。 いったいどうしてでしょうか?教えてください。 よろしくお願いします。m(__)m ---以下ソースサンプル(サブルーチンは省略)--- #!/usr/bin/perl #日本語コード処理ライブラリ require './jcode.pl'; # ↓保存されるファイルの漢字コード('sjis' 'euc' 'jis' のいずれか) $kanjicode = 'sjis'; $logfile = './circle.log'; ############################# # メイン処理 ############################# &init_form($kanjicode); print <<HTML; Content-type: text/html <HTML> <BODY> HTML if($form{mode} eq 'comm') { &viewComment; } &viewList; sub viewList { open(IN,"$logfile") || &error("Open Error : $logfile"); while (<IN>) { ($no,$reno,$date,$name,$mail,$sub,$comment,$url,$host,$pw,$color,$icon) = split(/<>/); if ($reno eq "") { print <<"HTML"; [$no] <A href="$C?page=$no&mode=comm">$sub</a><br> HTML } } print <<HTML; </BODY> </HTML> HTML } sub viewComment { open(IN,"$logfile") || &error("Open Error : $logfile"); while (<IN>) { ($no,$reno,$date,$name,$mail,$sub,$comment,$url,$host,$pw,$color,$icon) = split(/<>/); if ($reno eq $form{page} || $no eq $form{page}) { print <<"HTML"; [$sub <a href="mailto:$mail">$name</a> $date]<br> $comment <HR> HTML } } print <<HTML; </BODY> </HTML> HTML exit; }

    • ベストアンサー
    • CGI
  • perl-cgiのサイズと実行速度について

    perl-cgiのサイズと実行速度について 下記のように、$ENV{'QUERY_STRING'}の値によって、使う、サブルーチンを振り分けているCGIが2つあります。 sub app*は非常に似たような内容で、ひとつの大きさが200KB程度あります。 sample1.cgi と sample2.cgi ではサーバのCPU時間にどの程度の影響がありますか? CGIの内部でベンチマークを取得してみたところ、sample2.cgiでは、0.02cpu程度上昇した程度で、大きな差は見られませんでした。 しかし、共有の、レンタルサーバで使う予定ですが、その場合、毎回、200KBのCGIをコンパイルして実行と、毎回、400KBのCGIをコンパイルして実行されるため、ベンチマークでは計りきれないところが心配です。 また、CPU時間に差が出たとしても、それは、無視できる程度の物でしょうか? まったく持って、見当が付きませんので、どなたか、ご存知の方、教えていただけると幸いです。 宜しくお願い致します。 =sample1.cgi============== $qs = $ENV{'QUERY_STRING'}; if($qs eq 1){ &app1(); }else{ &app2(); } sub app1(){ #いろいろ } sub app2(){ #いろいろ } =sample2.cgi============== $qs = $ENV{'QUERY_STRING'}; if($qs eq 1){ &app1(); }elsif($qs eq 2){ &app2(); }elsif($qs eq 3){ &app3(); }else{ &app4(); } sub app1(){ #いろいろ } sub app2(){ #いろいろ } sub app3(){ #いろいろ } sub app4(){ #いろいろ }

  • Locationを使いたいのですが

    はじめて質問します。よろしくお願いします。 フォームからデータを受け取って、なんらかの処理をしてから、 locationで別のページへジャンプしたいのです。 下のソースで、ローカル(win95)では正常に動いたのですが、 サーバーに移すと送信後のtest.cgiがエラーになってしまいます。 text.txtへの書込みはちゃんと行われています。 原因がわからなくて困っています。 locationの使い方が間違っているのでしょうか? ↓↓ test.cgiソース ↓↓ ------------------------------------------------------------ #!/usr/bin/perl require 'jcode.pl'; &decode; if ($FORM{'cmd'} eq "regist") { &write; # ファイル書込み print "Location: index.html\n\n"; } else { print <<END; Content-type: text/html <HTML><HEAD><TITLE>タイトル</TITLE></HEAD> <FORM ACTION="test.cgi" METHOD="POST"> <INPUT TYPE=TEXT NAME="message" VALUE=""> <INPUT TYPE=SUBMIT NAME="submit" VALUE="送信"> <INPUT TYPE=HIDDEN NAME="cmd" VALUE="regist"> </FORM> </BODY></HTML> END } exit; # ファイル書込み sub write { open OUT, ">test.txt"; print OUT "$FORM{'message'}\n"; close OUT; }

    • ベストアンサー
    • Perl
  • cgiログデータ入力

    下記のようなものを作成しました。 if ($FORM{'WORD'} eq 'フォーム'){ &form; } elsif($FORM{'WORD'} eq '確認'){ &kakunin; } elsif($FORM{'WORD'} eq '入力'){ &nyuuryoku; } sub kakunin{ print "<FORM METHOD=POST ACTION=top_nyuuryoku1.cgi>\n"; print "<TABLE CLASS=TABLE2 CELLSPACING=0 CELLPADDING=2>\n"; print "<TR><TD WIDTH=80 CLASS=TD1>社員番号</TD><TD CLASS=TD2>$FORM{'BANGOU'}<INPUT TYPE=HIDDEN NAME=BANGOU VALUE=$FORM{'BANGOU'}></TD></TR>\n"; print "<TR><TD WIDTH=80 VALIGN=TOP CLASS=TD1>本文</TD><TD CLASS=TD2>$FORM{'NAKAMI'}</TD><INPUT TYPE=HIDDEN NAME=NAKAMI VALUE=$FORM{'NAKAMI'}></TR>\n"; print "</TABLE>\n"; print "<BR>と入力されました。これでよければボタンを押してください。<BR><BR>\n"; print "<INPUT TYPE=HIDDEN NAME=WORD VALUE=入力>\n"; print "  <INPUT TYPE=SUBMIT CLASS=BUTTON VALUE=入力>\n"; print "</FORM>\n"; } sub nyuuryoku{ print "入力しました。<BR>\n"; print "<A HREF='top.cgi'>戻る</A>\n"; open (FILE,">>top.log"); flock(FILE,2); @FILES = "$buffer\n"; print FILE @FILES; flock(FILE,8); close(FILE); } ※多少省略あり。 ※$bufferはこれの前のページから受け取ったもの。 kakuninのところの$FORM{'NAKAMI'}ではちゃんと半角スペースや改行が認識されていますが、nyuuryokuになるとだめです。 一体何が原因なのでしょうか?

    • ベストアンサー
    • CGI
  • CGI間のデータ送信について(perl)

    perlのcgiで詰まってしまったので質問します。 現在困っていることは、cgiからcgiへの変数の値の受け渡しについてです。 色々調べてやってみたのですが、うまくいきません。 送信側で print "<form action = \"sendmail.cgi\" method=\"post\">"; print "<A href =\"sendmail.cgi?$array1[0]&$array1[1]&$array1[2]&$array1[3]\">sendmail.cgi</A>"; print "<input type=\"submit\" value=\" ボタンです。 \">"; print "</form>"; として 受信側で # postでもgetでも受信できるようにする if ($ENV{'REQUEST_METHOD'} eq "GET") { $data = '1'; $testmsg = "GETで受信"; $formdata = $ENV{'QUERY_STRING'}; print("$formdata<BR>"); } elsif ($ENV{'REQUEST_METHOD'} eq "POST"){ # こちらを使用している $data = '2'; $testmsg = "POSTで受信"; $length = $ENV{'CONTENT_LENGTH'}; read(STDIN,$formdata,$ENV{'CONTENT_LENGTH'});# $dataに受信する print("$formdata<BR>"); } else { $data = '3'; $testmsg = "受信することができませんでした。<BR>"; } としてpostにて受信しようとしています。 postのif文には入ったようなのですが、データが空っぽで何も入っていないようなのです。 何が原因なのでしょうか?助けてほしいです。

    • 締切済み
    • CGI
  • if ステートメントについて質問

    今ifステートメントについて勉強してるのですが 自分が調べた感じではこのように書いてありました。 If condition Then [statements] [ElseIf condition-n Then [elseifstatements]] . . . [Else [elsestatements]] End If しかし、以前に作った掲示板のメイン処理のあたりを見てみると、↑のようでなく if ($mode eq "howto") { &howto; } elsif ($mode eq "find") { &find; } elsif ($mode eq "usr_del") { &usr_del; } ・ ・ ・ 見たいな感じです。これは今自分が勉強しているところと違うところですか?

    • ベストアンサー
    • Perl
プリンターの設定ができない
このQ&Aのポイント
  • PIXUS MG3630を使用していますが、MacOS Sonoma14.1.2での設定ができません。
  • 公式サイトにはMacOS 14の記載がないため、プリンターが対応していない可能性があります。
  • キヤノン製品に関する質問です。プリンターの設定についてお知恵を拝借したいです。
回答を見る

専門家に質問してみよう