2022-01-14 VBA 関数の仮引数はどうあるべきか。暗黙の型変換をどうやって回避するか

1
ほえほえ@スプシマン @hoehoe1234

この部分を間違えて解説している記事、書籍がありますので注意してください。 ②参照型バリアント仮引数   実引数 仮引数(バリアント) 1)値型  実引数へのポインタ 2)参照型 実引数へのポインタ 3)配列型 実引数へのポインタ 4)バリアント 同じ変数 となります。

2022-01-25 02:02:12
ほえほえ@スプシマン @hoehoe1234

形の違う(実引数は値型、参照型、配列型)仮引数なのに参照型として1)~3)が振る舞うのは、仮引数の場アリアントがポインタとして実装されているからなんですね。この仕組を知ったときはよく出来ているなと思いました。

2022-01-25 02:03:53
ほえほえ@スプシマン @hoehoe1234

注目したいのは4)です。実引数と仮引数が共にバリアントであると(バリアントの種別は4種類あります、別記事)同じ変数として扱われますので、コピー、暗黙の型変換などが一切行われずに関数の深いところまで変数をそのまま届けることができます。透過性があるんですね。この性質はとても好ましい

2022-01-25 02:05:42
ほえほえ@スプシマン @hoehoe1234

ものです。途中にある関数は、識別子で縛られますが、その型には縛られません。末端の最後の具体的に操作を行う関数に、変数の情報にノータッチで伝えることができるんですね。共通関数、ライブラリでは特に重宝する機能だと思います。

2022-01-25 02:07:12
ほえほえ@スプシマン @hoehoe1234

仮引数の比較です。 ①値型バリアント仮引数 a)具象型のコピーは問題ない b)配列のコピーは時に問題 c)実引数を書き換える心配がない ②参照型バリアント仮引数 a)具象型実引数へのポインタとなる b)配列のコピーが発生しない c)実引数を書き換えられる d)変数を引数をスタックに

2022-01-25 02:09:55
ほえほえ@スプシマン @hoehoe1234

積まずにどこまでも深く渡していける という違いがあります。安全性からは①のほうがよいとは思いますが、滝Libでは全面的に②を採用しています。①と②、どちらを選んでも安全に型のチェックが行え、ゴミが入ったら診断を出せます。

2022-01-25 02:11:41
ほえほえ@スプシマン @hoehoe1234

やっと、デフォルトプロパティを制御可能な階層型型判定関数群が動いた・・・。簡単そうにみえて難しかった。この関数群を利用することで「ゴミが入ったら診断が出る」と実装することができます。 pic.twitter.com/AURCRJ5F9X

2022-01-26 02:51:38
拡大
ほえほえ@スプシマン @hoehoe1234

この結果から、仮引数を具象型とすると如何に脆弱な関数になるかがわかるかと思います。関数が脆弱というよりも暗黙の型変換を防止できないので「ゴミが入ったらゴミが出る関数」にならざるを得ないのですね。これはスクリプト言語の基本である「ゴミが入ったら診断が出る」に反しています。 pic.twitter.com/lg5Zr4QgTW

2022-01-26 03:03:22
拡大
ほえほえ@スプシマン @hoehoe1234

こちらが本来あるべき、「ゴミが入ったら診断が出る」実装です。仮引数をバリアントで受けて必要があれば引数の型を調べます。仮引数をバリアントとすることで暗黙の型変換を回避できます。 pic.twitter.com/Uz4k5PmUik

2022-01-26 03:12:17
拡大
ほえほえ@スプシマン @hoehoe1234

これらの結果をみるとバリアントでの+演算の結果が文字連結になってしまうことをことさらに強調するのがおかしいということがわかります。もちろん、暗黙の型変換は呼び出し側、+演算子の誤適用は呼び出された側の問題なので少々性格は異なりますが、後者は単にCDbl(引数)とすれば良いだけです。

2022-01-26 03:15:15
ほえほえ@スプシマン @hoehoe1234

先程の関数を変更して「実数」を受け入れるようにチェックを変更してみました。具象型仮引数に比べて遥かに堅牢な関数が書けるのがわかると思います。 pic.twitter.com/xr3hiBP9qV

2022-01-26 03:19:15
拡大