none
VB6のGoSubをVB.NETで書き換える方法について RRS feed

  • 質問

  • お世話になっております。
    VB6からVS2015へのアップグレードを検討しています。
    VB6のソースではGoSubをいたるところで利用していて、VB.NETではGoSubが使えないので書き換える必要があります。
    VS2010以降であればクロージャーで書き換えることが可能なようなのですが、VB6のソースでは「On Err GoTo」も使っていて、クロージャーで書き換える場合は例外処理の部分も「Try - Catch」で書き換える必要が出てきてしまいます。
    VB6のソースには700画面ほどあり、手順書を作成して複数人で手順書に沿って書き換えることを検討しています。そのため、書き換える手順として定義しやすく、また、担当者によってばらつきが出ない方法を選択する必要があります。
    クロージャーへの変換は、担当者でどのようにソースを修正するのかの判断が必要になってしまうかと考えていて、GoSubの部分を別関数として抜き出す方法を取ろうと考えています。

    どなたか、GoSubの書き換えを経験したことがある方いらっしゃいますでしょうか。
    クロージャーを利用するのと、別関数に抜き出すのと、どちらのほうが単純作業でできるのかご意見いただけますか。
    2017年7月24日 2:56

回答

  • GoSubの書き換えを経験したことはありませんが、クロージャを使うのは良いアイディアだと思います。
    GoSub内でのみスコープを持つローカル変数は定義できませんから、別関数にする場合、変数をグローバル変数として関数外に定義する必要が生じる場合があります。一方、クロージャにする場合、同様にレキシカル変数として抜き出す必要があります。
    どの変数をグローバル、もしくはレキシカル変数にするかを考えるよりは、全ての変数をグローバル、もしくはレキシカル変数にしてしまう方が単純作業で間違いがないように思います。
    ただ、グローバル変数には弊害がありますので、バグにつながりやすい側面があります。

    また、クロージャにする場合、Try - Catchに書き換える必要があるとのことですが(ラムダ式内でOn Err GoToが使えないのが理由ですよね?)、そもそもTry - Catchはよほどのことがない限り書く必要はないので、これを機会に整理されると良いと思います。Try - Catchのこの辺りに関しては以下をご覧ください。
    (参考)
    .NETの例外処理 Part.1
    https://blogs.msdn.microsoft.com/nakama/2008/12/29/net-part-1/


    まとめると、

    1.別関数にする場合、プロシージャが別になり、グローバル変数を使用しなければならない場合がある。
    クロージャだと同一プロシージャに書け、同一プロシージャでしか定義できないGoSubと合致し、わかりやすい。また、グローバル変数を使わなくても良い。

    2.グローバル変数にしてもレキシカル変数にしても、GoSubからどの変数を対象とするのかを抜き出すのが大変である。単純に全ての変数をグローバル変数、もしくはレキシカル変数にするというポリシーだと、人によって作業にバラツキが生じず、バグも発生しにくい。

    以上より、別プロシージャ、およびグローバル変数を使う必要がなく、単純に全ての変数をレキシカル変数にしても動作に支障がないクロージャで置き換える方が良いのではないかと思います。


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/


    2017年7月25日 4:58
    モデレータ

すべての返信

  • GoSubの書き換えを経験したことはありませんが、クロージャを使うのは良いアイディアだと思います。
    GoSub内でのみスコープを持つローカル変数は定義できませんから、別関数にする場合、変数をグローバル変数として関数外に定義する必要が生じる場合があります。一方、クロージャにする場合、同様にレキシカル変数として抜き出す必要があります。
    どの変数をグローバル、もしくはレキシカル変数にするかを考えるよりは、全ての変数をグローバル、もしくはレキシカル変数にしてしまう方が単純作業で間違いがないように思います。
    ただ、グローバル変数には弊害がありますので、バグにつながりやすい側面があります。

    また、クロージャにする場合、Try - Catchに書き換える必要があるとのことですが(ラムダ式内でOn Err GoToが使えないのが理由ですよね?)、そもそもTry - Catchはよほどのことがない限り書く必要はないので、これを機会に整理されると良いと思います。Try - Catchのこの辺りに関しては以下をご覧ください。
    (参考)
    .NETの例外処理 Part.1
    https://blogs.msdn.microsoft.com/nakama/2008/12/29/net-part-1/


    まとめると、

    1.別関数にする場合、プロシージャが別になり、グローバル変数を使用しなければならない場合がある。
    クロージャだと同一プロシージャに書け、同一プロシージャでしか定義できないGoSubと合致し、わかりやすい。また、グローバル変数を使わなくても良い。

    2.グローバル変数にしてもレキシカル変数にしても、GoSubからどの変数を対象とするのかを抜き出すのが大変である。単純に全ての変数をグローバル変数、もしくはレキシカル変数にするというポリシーだと、人によって作業にバラツキが生じず、バグも発生しにくい。

    以上より、別プロシージャ、およびグローバル変数を使う必要がなく、単純に全ての変数をレキシカル変数にしても動作に支障がないクロージャで置き換える方が良いのではないかと思います。


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/


    2017年7月25日 4:58
    モデレータ
  • trapemiya さん、返信ありがとうございます。

    また、ご連絡が遅くなり申し訳ありませんでした。

    クロージャで置き換える方針で検討してみます。ありがとうございました。

    2017年8月30日 23:09