別件でScilabを使わせていただいていたときに、「不可解」な挙動に遭遇。よく見てみれば、私がScilab既定の関数と同名の変数を作って値を代入していたために発生した問題だったです。でもね、Scilabって関数を再定義してしまうと警告してくれるのがデフォルトじゃなかったっけ?
※「トホホな疑問」投稿順Indexはこちら
※Scilab 6.1.1 (Windows上)で動作確認しています。
※Scilabで「不可解」な挙動に遭遇した記事は以下です。
手習ひデジタル信号処理(67) Scilab、IIRフィルタでフィルタしようとしてハマった件
不可解な挙動の実際
正常に動作していた筈の関数Aが、別の関数Bを動かしたら急に動かなくなりました。かいつまんでエラーを説明すると以下のようです。
-
- 関数Aに引数与えて正常に返り値が返るのを確認した。
- 関数Bの返り値を coeff なる変数に代入した。
- その直後、関数Aに1と同様な引数与えると、エラーで落ちるようになった
ぶっちゃけエラーの原因は以下でした。
-
- 関数Aから呼び出している「孫」レベルの関数内でcoeff関数(Scilabの規定の関数)を呼び出していた。
- coeffという変数に値を代入したことで、関数coeffは、変数coeffに解釈されてしまいエラーを起こすようになった
Scilab素人の私が、Scilabに coeff というお名前の関数(多項式から係数ベクトルを抽出する関数)が存在することを知らなかったがための不手際。悪いのは私です。
関数を「再定義」したのであれば警告が出るが。。。
例えば testCCC()という関数を一度定義した後で、以下のようにもう一度定義してみると警告が出ます。
上に見えるように、デフォルトでは警告が表示されるだけで、再定義を妨げることはないです。なお上記でピンク色の「funcport」と書かれている部分は日本語エラーメッセージのタイポじゃないかと思います。正しくは、
です。funcprot()関数に0を与えると再定義しても警告でなくなりますし、2を与えればエラーにできるようです。
関数と同名の変数に値を代入しても警告されない
まずは、関数の内部からトップレベルで定義した変数の値が参照できることを確かめてみます。こんな感じ。
関数testCCC()を走らせると、上記のように関数名testCCCを印字するとともに、トップレベルの変数 aaa の値を表示します。関数内部から外側の変数は見えることが確認できます。
さて、ここで関数testCCCと同名の変数にベクトルを代入してみます。そして testCCC()としてみるとこんな感じ。
あちゃ~ testCCC()としても、変数testCCC()のベクトル値が返ってくるのね。関数として再定義しようとしたときに警告など無しです。
関数と同名の変数を「うっかり」作ってしまうと酷いことになるかも
ってことですかい。トホホ。
なお、ベクトル値を格納した testCCCに対して、再度関数として定義しても警告はでません。
なお、coeffのように、Scilab既定の関数は、変数をclearすれば再び使えるようになりました。
Scilab既定の関数、やたら多いからとても覚えきらんよ。変数名にありがちな名前を使わん方が身のため?トホホ。