Chinaunix首页 | 论坛 | 博客
  • 博客访问: 100585
  • 博文数量: 20
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 455
  • 用 户 组: 普通用户
  • 注册时间: 2007-06-06 11:04
文章分类

全部博文(20)

文章存档

2011年(1)

2010年(14)

2009年(4)

2008年(1)

我的朋友

分类:

2010-07-28 15:37:32

> 第8章 サブルーチン
  第8章 サブルーチン



8-1. サブルーチンの定義と呼び出し

  • サブルーチンとは、スクリプトの内部をモジュール化(部品化)する手法をいいます。いわば自分で関数を作成・定義するための手法です。このため、サブルーチンは「ユーザ関数」とも呼ばれることがあります。
  • スクリプトを記述する際に、サブルーチンを作成するメリットとして、次の2点が挙げられます。

    1. CGIスクリプトの中で、ある処理を何度も反復使用したりする場合に、その処理部分をモジュール化して、呼び出すことで効率的なプログラムを記述することができる。
    2. CGIスクリプトの記述が長くなると、一般的にスクリプト全体の流れが理解しづらくなるが、このときに、全体的な処理を記述するレベル(サブルーチンの呼び出し)と、個々に細かく処理するレベル(サブルーチンの作成)を分けて、全体の見通しをよくする工夫ができる。


  • サブルーチンを作成するには、次のような構文で定義します。

    サブルーチンの定義
    sub サブルーチン名 { 処理 }
    (sub + 半角スペース + サブルーチン名 + ブロック)


  • このサブルーチン名の付け方の制約は変数名と同じです。また、サブルーチンの定義部分はスクリプトのどこに置いても構いませんが、一般的には最後に置かれます。
  • サブルーチンを呼び出すには次のようにします。呼び出されたところで、定義されたサブルーチンが呼び出され実行されます。

    サブルーチンの呼び出し
    & サブルーチン名
    (アンパサンド + サブルーチン名)


    ▼サブルーチンの使用例
    $x = 80;
    $y = 55;
    $z = 75;

    &answer;

    sub answer {
         $total = $x + $y + $z;
         $mean = $total / 3;

         print "
    合計点数は$total点で、平均点数は$mean点です。\n";
    }


    <出力結果>
    合計点数は210点で、平均点数は70点です。




8-2. 引数と戻り値
  • サブルーチンとは、ユーザが自由に定義できる関数ですから、サブルーチンに引数を渡したり、またサブルーチン実行後に戻り値を返すこともできます。
  • 引数は配列 @_ に格納されて渡されます。

    ▼サブルーチン abc に、引数 @list を渡すとき
    引数の渡し方 &abc(@list);
    引数の受取り サブルーチンabcは、@list を、配列 @_ で受け取る


    &answer(80, 55, 75);

    sub answer {
         ($x, $y, $z) = @_;
         $total = $x + $y + $z;
         $mean = $total / 3;

         print "
    合計点数は$total点で、平均点数は$mean点です。\n";
    }


    <出力結果>
    合計点数は210点で、平均点数は70点です。


  • サブルーチンの戻り値return を使って戻すことができます。

    ▼サブルーチン abc の戻り値を @back とし、それを @list で受け取るとき
    戻り値の戻し方 sub abc {
        
    実行文

         return @back;
    }
    戻り値の受取り @list = &abc;
    (サブルーチンを右辺に定義する)


    ($total, $mean) = &answer(80, 55, 75);
    print "
    合計点数は$total点で、平均点数は$mean点です。\n";

    sub answer {
         ($x, $y, $z) = @_;
         $total = $x + $y + $z;
         $mean = $total / 3;

         return ($total, $mean);
    }


    <出力結果>
    合計点数は210点で、平均点数は70点です。




8-3. 局所化
  • プログラムが数千行、数万行と膨大になってくると、どうしても使用する変数が重複するようになってきます。また、重複を回避させるために毎回異な る変数を充てるのにも限度があり、混乱や誤りを招いてしまいますし、膨大なプログラムである程、変数の数を絞ったほうがメモリの節約になります。
  • そこで、変数をサブルーチンなどのブロック内だけに通用させるようにする必要がでてきます。これを局所化といいます。

  • 局所化という観点に基づいたとき、変数の特性は2つに分けられます。プログラム(スクリプト)全体で参照可能な変数をグローバル変数といい、サブルーチンなどのブロックの中だけで利用可能な変数をローカル変数といいます。
  • 変数は、初期値としてはグローバル変数となりますので、特に何も定義をしない変数はすべてグローバル変数とみなされます。
  • 変数をローカル変数として定義する場合には、local または my を使用します(local と my の違いについては次節で説明します)。まずは以下の例を見てみましょう。

    1| $word = "晴れ";
    2| &yesterday;
    3| print "
    今日は$wordです。\n";
    4|
    5| sub yesterday {
    6|      $word = "
    ";
    7|      print "
    昨日は$wordでした。\n";
    8| }


    <実行結果>
    昨日は雨でした。
    今日は雨です。

    1行目で変数 $word に「晴れ」が代入されていますが、次の yesterdayサブルーチンが実行されて、$word に「雨」が代入されたため、3行目の $word は「雨」で実行されています。
    これは変数が重複したために期待しない結果になってしまう一例です。
    そこで、次にサブルーチン内の変数をローカル変数で定義して局所化してみましょう。

    1| $word = "晴れ";
    2| &yesterday;
    3| print "
    今日は$wordです。\n";
    4|
    5| sub yesterday {
    6|      my $word = "
    ";
    7|      print "
    昨日は$wordでした。\n";
    8| }


    <実行結果>
    昨日は雨でした。
    今日は晴れです。

    サブルーチン内で my を使って変数 $word を局所化したため、6行目で代入された「雨」はサブルーチンを抜けた瞬間消滅してしまいます。したがって、3行目の変数 $word は期待どおりに「晴れ」が実行されることになります。
    ちなみに、今回の例文では my の代わりに local を使用しても構いません。(同じ結果になります)




8-4. local と my の違い
  • ローカル変数を宣言する関数として、local と my の2つがありますが、この2つの関数には次のような特性とそれぞれの相違が存在します。


    local my
    Perlバージョン Perl4, Perl5 Perl5のみ
    局所化の特性 宣言されたサブルーチンから呼び出されたサブルーチンからは参照が可能。 完全に局所化されるため、localのように、サブルーチンから呼び出されたサブルーチンからも参照することはできない。


    $word = "晴れ";
    &today;

    sub today {
         local $word = "
    ";
         &yesterday;
         print "
    今日は$wordです。\n";
    }

    sub yesterday {
         print "
    昨日は$wordでした。\n";
    }


    <実行結果>
    昨日は雨でした。
    今日は雨です。


    $word = "晴れ";
    &today;

    sub today {
         my $word = "
    ";
         &yesterday;
         print "
    今日は$wordです。\n";
    }

    sub yesterday {
         print "
    昨日は$wordでした。\n";
    }


    <実行結果>
    昨日は晴れでした。
    今日は雨です。

阅读(1166) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~