グローバル変数の弊害について

はてなブックマーク - グローバル変数の弊害について
このエントリーをはてなブックマークに追加
Share on Facebook

先日書いたフィボナッチ数を出力するコードだけれど、
「グローバル変数を使わないで書いたほうがいいよ」
というアドバイスを頂きました。

ということで、グローバル変数を使うことのデメリットについて調べてみました。
まず、グローバル変数とは・・・・

プログラミングにおいて全てのスコープからアクセスできる変数のこと

です。
ちなみにスコープとはある変数や関数が特定の名前で参照される範囲のこと。
ようするに全てのスコープというのはプログラム全体という意味。
どこからでも呼び出せて書き換えられる変数ということです。

なので、「ついつい便利だから使っちゃうんだよな・・・。」と思っていたらwikipediaに
はっきりと悪しき慣習と考えられている
と書かれていました。

グーグルでグローバル変数 弊害で検索してみたところ出るわ出るわ。
というわけでグローバル変数の弊害についてまとめてみました。

どこで値が書き換わるか予測できない
→バグが発生しやすくなる。(もちろんバグがあった場合の対処も大変)
→メンテナンスがしづらくなる。(特に他人が書いたコードだと、プログラム全部を見直さないといけない)
→複数のグローバル変数を使うとコードの複雑性が増す。(使えば使うほど複雑に。そして上記2点もさらに難解に・・・)

というのが、主な理由のようです。

では、どうすればいいのかということですが、

なるべく使わない。
変数は引数で渡す。

のが良さそうです。

どうしても使いたいとき。
例えば、
「様々な関数内でよく使われている変数を引数として渡すのを避ける時」
「それぞれのページで共通に つかうグローバル変数」
こんなときは、別のファイルにまとめてrequireで取り込んだりして工夫する必要があるようです。

また、PHPではphp.iniのregister_globals=onのとき、$_POST['a']は$aというグローバル変数で呼び出せてしまうので、URLを書き換えることによって変数を自由に書き換えられるセキュリティ上の問題があります。
(php4.2移行でデフォルトoffになった)

こんな内容の情報も。
「優れたプログラマはグローバル変数の弊害に気づいているので、削減に努力している」
「無能はプログラマや初心者ほどグローバル変数を多様し、修正と解読が困難なスパゲッティコードを書く」

う・・・耳が痛い。
こういったプログラムを書く上で知っておくべきことを学ぶのも、今後の課題だと気づかされました。

修正したフィボナッチ数出力プログラム

<?php
$f['1']=1;
$f['2']=1;
$limit=$_GET['i'];
$i=3;

if(!(preg_match('/\\d/',$limit)) or $limit<1){
	$result='1以上の整数を入力してください';
}else{
	$result=f($i,$limit,$f);
}

function f($i,$limit,$f){

	//1か2が渡された場合は1を返す
	if($limit<3){
		$result=$f[$limit];
		return $result;
	}

	$f[$i]=$f[$i-1]+$f[$i-2];
	$i++;
	if($i>$limit){
		$result=$f[$i-1];
		return $result;
	}else{
		return f($i,$limit,$f);
	}
}

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
 <head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>再帰関数でフィボナッチ数を取得(修正版)</title>
<style>
<!--
-->
</style>
<script type="text/javascript"><!--
// --></script>
</head>
<body>
	<h1>再帰関数でフィボナッチ数を取得(修正版)</h1>
	<p>何番目のフィボナッチ数を取得しますか?</p>
	<form method="get" action="./">
		<input type="text" value="" name="i" />
		<input type="submit" value="送信" />
	</form>
	<p style="margin-top:2em"><?=$result?></p>
</body>
</html>

コメントをどうぞ

メールアドレスが公開されることはありません。

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <img localsrc="" alt="">