02. 制御構文
ここは、一般的な制御構文(条件分岐、ループ文)を取り扱います。他の多くのサイトで確認可能な内容ですが、まとめておきたいと思います。なお、RubyやPythonに関しては、あまり深入りしない程度にとどめます。
--- tcsh
制御構文を書くときは、スペースを入れるようにしましょう。ほんの数行のコードでは動くコードでも、数百行以上になった時、文法解析がおかしくなることがあります。こうなると、どこが原因か区別がつかなくなり、Debugがたいへんです(経験上の話)。if($a==1)then → if ( $a == 1 ) then (それぞれにスペースを入れておく)
条件判断
$var == 1 (数値:浮動小数は扱えない)
使える演算子:==, >, >=, <, <=, != など
$var == "test" (文字列)
変数内の文字列が、特定の文字列を含んでいるかどうか、というときは
簡単なパタンであれば、grepを使わずに済みます。「keyword」を含む、という意味で書くとき、
if ( $var =~ *keyword* ) then
処理
…という具合に書きます。「*」は簡易正規表現として扱われるようです。どこまでの表記が許されるかはわかりませんが、少し細かい条件を書くときは、下記のgrep/egrepで正規表現を利用するのが好ましいと思います。
*1 *keyword* は、「"」や「'」で括ってもかまいません
echo $var | grep "keyword" >! /dev/null
if ( $status == 0 ) then
処理
…という具合に書きます。
*2 "keyword" は 'keyword' でも可。grepだと正規表現も使えます
if ( $?var ) → 変数varが定義されているなら
例えば、環境変数が定義されていなければ、特定のファイルをsourceする、とかに使います
if ( ! $?ENV ) then
source xxx
endif
条件分岐
if
- if ( 条件 ) 処理
- if ( 条件 ) then
処理
else
処理
endif
- else if の書き方は「else if」
switch
- switch ( 変数 )
case 値 :
処理
:
breaksw
case値:
処理
:
breaksw
default:
処理
endsw
- *1 case文の最後にbreakswを入れ忘れると、次のcase文中の処理もしてしまうので注意してください
ループ
while
- while ( 条件 )
処理
end
*1 ループ内部で、条件がfalseになるようにコーディングしてください。goto文で抜けるのはお勧めしません
foreach
- foreach 変数名 ( リスト文字列 )
処理
end
*1 変数名には $ がつきません
*2 リスト文字列は、空白区切りされた情報を指します
- set list = ( a b c )
- set list = `ls *.xyz`
--- Perl
条件判断
$var == 1 (数値)
使える演算子:==, >, >=, <, <=, != など
$var eq "test" (文字列)
使える演算子:eq, ne, lt, gt, le, ge, =~, !~, cmpなど
変数内の文字列が、特定の文字列を含んでいるかどうか、というときは
$var =~ /keyword/
と書きます。keywordには正規表現が使えます。
未定義変数かどうかは
defined($var)
を使います。shellの環境変数を拾うには、
$ENV{'ENV'} #ENVは環境変数名を指定
と書きます。ハッシュ扱いされます。
条件分岐
if
- 処理 if(条件);
- if(条件){
処理
}elsif(条件){
処理
}else{
処理
}
三項演算子というものもありますが、ここでは扱いません。三項演算子のネストはほどほどに。
*1 Perlには標準でswitch文がありませんが、それに似たような文法はバージョン限定であるようです。「perl switch」などで検索してみてください
ループ
for
- for($i=0; $i<10; $i++){
処理
}
- 局所変数化してあげると、「この変数名使っていいんだっけ?」という悩みから開放されます
for(my $i=0; $i<10; $i++){
処理
}
局所変数定義であるmyとlocalは挙動が異なります。myを使う方が混乱しづらいと思いますが、詳しくは他のサイトを御覧ください。
foreach
- foreach 展開変数名(リスト){
処理
}
- *1 展開変数名は、$tmpなど。展開変数名は、自動的に局所化されるようです。
$ppp = 10;
@kkk = (1,2,3);
foreach $ppp(@kkk){
}
print $ppp."\n";
→ 10と表示されます(壊されていない)
while
- while(条件){
処理
}
unless
- unless(条件){
処理
}
--- Ruby
条件判断
var ==1 (数値)
使える演算子:==, >, >=, <, <=, != など
var == "test" (文字列)
使える演算子:==, >, >=, <, <=, != など
*1 Perlでは "==" を使わないが、Rubyでは "==" で比較します。
変数内の文字列が、特定の文字列を含んでいるかどうか、というときは
var =~ /keyword/ または
/keyword/ =~ var
と書きます。keywordには正規表現が使えます。
*1 文字列の正規表現マッチングは、変数varが「数値(Fixnum)」だとErrorになります。
未定義変数かどうかは
defined?(var)
を使います。shellの環境変数を拾うには、
ENV["ENV"] または
ENV.fetch("ENV")
と書きます。"ENV"は環境変数名を指定します。ハッシュ扱いされます。
条件分岐
if
- 処理 if 条件
- if 条件 then
処理
elsif 条件 then
処理
else
処理
end
*1 Rubyでは条件を()で括っても括らなくても構いません
case
- case 変数
when 値
処理
when 値
処理
else
処理
end
*1 値のところは、1,2,3... のように、カンマで複数値書くことができます
*2 値のところは、範囲演算子を用いて 1..3 というような表記もできます
ループ
種類が多いため、一部に限定します。こちらに、もう少し細かく書いています。
for
- for var in range do
処理
end
*1 var は、rangeを展開した数値を格納する変数名です
*2 range は、例えば「1..10」などの表記をします。rangeには、定義済み配列を置いてもいいです
array = [1,2,3]
for var in array do
処理
end
*3 varは、for文内のローカル変数として扱われないので、変数名に注意が必要です(for文自体、Rubyではfor文の外とScopeが別れないようなので、Perlのように my を定義すればいい、という話にならないため注意が必要です)
each
- array.each do |var|
処理
end
*1 array は、配列やrangeオブジェクト(range=1..3、など)が使えます
*2 var は、配列やrangeオブジェクトを展開した値を格納する変数名です
*3 var は、ローカル変数扱いされるため、その外側で同名の変数があったとしても、破壊されません。その意味では、「意図的」に、for文を使わずにeach文や、その他のループ文を使うという手もあります。
while
- while(条件)do
処理
end
times
- n.times do
処理
end
*1 10.times(10回)など、規定回数ループするときに使います
--- Python
条件判断
var ==1 (数値)
使える演算子:==, >, >=, <, <=, != など
var == "test" (文字列)
使える演算子:==, >, >=, <, <=, != など
変数内の文字列が、特定の文字列を含んでいるかどうか、というときは
'keyword' in var
と書きます。正規表現でマッチングするときは、import re を書いておいた上で
re.search('pattern', var)
と書きますが、PerlやRubyと異なり、結果がTrue/Falseではなく、マッチした結果か、Noneが返ってきます。ちょっと癖のある仕様だなと思います。(条件文が書きづらい)
*1 文字列の正規表現マッチングは、変数varが「数値」だとErrorになります。
*2 「含まれる」という意味合いでは、re.search(...)を使います。
*3 「合致する」という意味合いでは、re.match(...)を使います。
未定義変数かどうかは
'var' in locals()
を使います。shellの環境変数を拾うには、import os を書いておいて、
os.environ.get('ENV',"hoge")
と書きます。"ENV"は環境変数名を指定します。hogeは、指定した環境変数が存在しない時に返す値です。
条件分岐
if
- if 条件: 処理(1行処理)
- if 条件:
処理
elif 条件:
処理
else:
処理
*1 else if 文はelif(elsifではない)のでお間違えないようにしてください。
*2 Pythonに標準的なswitch文はありません
ループ
for
- for var in リスト :
処理
*1 リスト は、配列であったり、range(1,10)などで表記します。
*2 var は、ローカル変数ではないので、外に同じ名前の変数があると、破壊してしまいます。
*3 range(1,10)と書いた場合、展開されるのは1~9までなので、注意してください
while
- while 条件 :
処理