Perl で利用宣言時にモジュールをカスタマイズする


公開 (UL): 2021-12-17
更新 (UD): 2021-12-21
閲覧 (DL): 2022-12-07

この記事のもくじ

→本文へ
当サイトは SNS の公式アカウントがないので,「議論ネタ」にする際は,皆さんのブログ,メーリングリスト,SNS や掲示板などで,適当にハッシュタグを付けたりリンクを掲載するなどしてご利用ください。

前の記事

2021-06-01
Base54

次の記事

2022-04-04
サイトのローカル試験と実ウェブ上の差を縮める手法(Perl)

最近の記事

2022-08-09
代表的な画像ファイル形式一覧
2021-06-01
PPOP
2021-03-04
全角⇔半角の変換
2021-02-23
五十音の「辞書順」の処理
2020-12-22
年月日から曜日を求める数式
新着情報
She appears also the top page.

新着情報 Recent docs.

Sorry, but almost these pages are only Japanese.
「だし」に使われる障害者 «Japanese governments wrong use "inspirational porn" for costing increase to the nations.»
自賠責の保険料値上げは「交通事故障害者支援のため」と言っているが,じつは財務省が6千億借りて焦げ付かせている事実があるという話。
経費節減! 介護設備 DIY のヒント «The goods and works those cost very low for home care.»
トイレと浴槽に手すり設置, 布団からベッドへ,そして部屋の灯りをリモコン化……が計3万! ついでに猫ケージも手作り。
「Jアラート」がポンコツになる理由 «How does the J-alert become useless.»
情報を受け取れる人を減らしてミサイルの犠牲者を増やすオヤクショのシステム。
個人情報の提示要求者側に求められる責任 «The responsibilities of the government that wants some private infomations.»
給付金の手続きに突然「旧住所」の提示を求めて来たお役所の対応の疑問からその「責任」を考える。
日本の「IT 人材不足」の正体 «The simple reason why Japanese companies lack IT-skill.»
保険会社からのセキュリティガバガバメールが「IT 人材不足」の正体を暴く。
「マイナンバー」が危険なこれだけの理由 «The reasons of "My-Number System" is danger.»
それでも「マイナンバー」を推す裏の理由を推察。

人気記事 Frequent view pages.

オランダの介護に対する考え方一例
人気急上昇中! 検索語「オランダ 介護の考え方」での上位御礼!
表計算で「令和」に対応する方法
How to adapt the Gengo era "Reiwa" on spreadsheet applicaiton.

古いアプリも OK。「表計算 令和」の検索結果上位御礼!
表計算ソフトで予定表を自動作成する超便利な方法 «How to make the schedule table automatically on spread-sheet.»
「毎月第○×曜日」的な法則は自動で作らせてラクしよう!
表計算ソフトに「個人情報保護機能」を仕込む方法 «Prevention to leak private-data with spread-​sheet macro function.»
「漏えい」のためのフェイルセーフ。「表計算 個人情報」の検索結果上位御礼!
Wary-Basher (ワリバッシャー)
DIY device that enables the handicapped to operate many things with a switch like push-button.

障害者の様々な操作をスイッチ操作で実現する器具。キットも発売中! 「作り方」PDF ダウンロード多数御礼!←地方教育委で人気。
貧乏人を殺す行政の構造 «Structurally, the administrators kill the poors in Japan.»
ヘタすると多摩川に流されるところだった台風 19 号

この記事に対する → 調布市の反応

おすすめ! Recommend

文字ベース天気予報 «Weather forecast in text mainly from JMA Json-data.»
古いブラウザやスマホ,音読ソフトでも大丈夫! 気象庁の JSON データを利用した文字ベースの天気予報(試験版)。
「事故防シート」について «Cared persons taking with "Jiko-​Bow-​Sheet" prevents from accidents.»
介護現場の負担軽減と事故防止のアイデア
【連載】 キーボードの「キー」の詳しい使い方 «The detial of usage each key on keybord.»
各キーの機能詳細。機能別五十音順一覧。
和易ゐ記 (WAI-WIKI) «WAI-WIKI is light­weight markup language for Japanese, and generates HTML on this server on-​demand.»
当サイトで開発/使用中の日本語向けに特化した軽量マークアップ言語
コロナ検査所一覧 «Light search for corona-test station.»
東京都サイトで配布の CSV ファイルを元に検索。スクリプト不使用のため,古い機械やブラウザ,音読ソフトでも大丈夫!

ご連絡 Contact

▼ メールフォームはこちら
SSL 証明書の更新に不具合が多いため,期限切れエラーが出た際は,お手数ですが「例外指定」をお願いいたします。

ファイルの暗号化
当サイト管理者(石川)宛にメール添付で送信するファイルを暗号化したい時は,唯一のパスワードを PPOP で取得できます。 PPOP gives a password for encryption of the file(s) attached your mail to the admini­strator of this site M.Ishikawa.
PPOP

時事川柳 News Senryu

杖をつく
 以前に思考は
  障害者

 例の某氏の発言……「杖をついていると身体障害者に見えて, みんなが大事にしてくれる」。このお方の思考が, いかに世の中とズレているかは明らか。 問題なのは,そんな方を「担ぎ出す人」のほうだと思う。 「来賓」として出席したのが,金沢医科大の記念式典だとかで, その大学の「顧問」らしい。つまり「金沢医科大学」の人たちは, そういう思考をする方を顧問にして平気でいられるということ。 (2022-10-30)

ご支援 Support this site.

まだまだ コロナ失業中!!
CORONA-NEET, seeking works now!

この活動をご支援いただける方はこちらへ Could you support this site, see here (but Japanese).
都道府県庁さん, 地方自治体さんや教育委員会さん, 障害者就労支援機関さんやその他公的機関,省官庁さん, 「タダ見」しているだけでは, 格差が広がるだけだと思いませんか?

 Perl modules have no notation for custom initializing from external proccess on DECLARATION of "use" or "require". Generally, like a constructor method sub named "new" implements it. But it has a possibility repeating similar initializing proccess on "new" sub and declaration. And I'm afraid that will be a waste operation.

 use や require などのモジュール利用宣言の初期化には,宣言時に行なわれるものと,コンストラクタ(new など)の初期化を含む手続きの呼び出しによるものとがある。そのモジュールを使う側特有の条件を「パラメータ」などとして与えて初期化したい時は,通常は後者の方法になるが,宣言時に行なわれた初期化と処理が重複する可能性がある。しかもこの方法は,「使いたい側が希望する条件では使えない」状況の時に,なるべく早い段階で感知したいと思っても,そのコンストラクタ的な手続きを呼び出すまで分からず,結果的に遅い場合も考えられる。「利用宣言時」の段階で分かればそれに越したことはないが,Perl では呼び出す側で設定したい値を「利用宣言時に」パラメータとして指定するなどの方法でモジュールに渡す方法は,特に用意されていない。
 「利用宣言時」にカスタマイズ的に初期化する「手段」として Perl に用意されているものはないが,調べたところ代替的に使えそうな方法があったのでメモ。

● 詳細

 一般的にモジュールの初期化は,use 宣言などをした時に行なわれるもの(実質的な BEGIN { …… } 処理)と,コンストラクタ的メソッド(通常は new)など「初期化」を含む手続きの呼び出しによりされるものがある。呼び出す側で独自の値を指定して初期化したい場合,たいていは宣言後にコンストラクタ相当の初期化を含む手続きにパラメータを与えて呼び出す方法になるが,場合によっては,モジュールの使用宣言をした時の初期化とコンストラクタ内で,似たような手続きを繰り返す可能性も考えられ,すると宣言時の初期化は半ば無駄な処理になる。
 一方で,もしモジュールの利用宣言をする側にとって目的通りの動作ができない状況があれば,なるべく早い段階……つまり,宣言の初期化時にエラーを返すなどで判明して欲しい場合もあると思われる。
  use や require といった利用宣言時点で,呼び出す側の都合で設定した値によってモジュールを初期化できれば,宣言時点の早い段階での動作確認ができるうえ,無駄な初期化処理もせずに済みそうな気がするが,Perl では宣言時に呼び出す側でそのモジュールに対し何らかの値を指定する方法は用意されていないうえ,use や require で呼び出し宣言されるモジュール内から直ぐ外側(そのモジュール使用を宣言した別のモジュールやスクリプトなど)の変数の値を確認する手段もない。そのため,呼び出す側の事情でカスタマイズした「初期化」をしたくても,「宣言」時点でそれをするための手段がなく,このままだと前述の「無駄な初期化」になると思われる処理を回避することはできない。

 ただ,perl の変数のうち“^_”で始まるものは,必ずグローバルな(main パッケージに属する≒%ENV などに似た)扱いになるのだとか。これを利用すると,呼び出されたモジュール内からもその値が読める。だから,require でモジュール利用を宣言する BEGIN 手続き内にその名前で変数を設定すれば,それは初期化時にも読めるわけで,「初期化手続き」に反映することができる。さらに,local 宣言をしておけば,BEGIN {} 内でのみ有効となり,他の手続きへの影響も避けられる。
 なお,この変数名に {} 括弧は必須らしい(${^_varname} など)。また“^_”自体は予約されているとかで,必ず文字の続く変数にする。

 Perl variables named prefix "^_" (e.g. ${^_varname} ) are accessible from any modules. Then in BEGIN { ... } proccess, you set "^_" prefix variable and use a module by "require", the module can access the variable on the declaration, and initialize with the value of the variable, before call initialize sub (e.g. new() constructor).

◆ 例(example)

 たとえば,こんなモジュールがあったとする。

▼ モジュール INITABL.pm
   package INITABL;
   my	$test;
	  if( exists ${^_INITABLini}->{ test } ){
	  $test = ${^_INITABLini}->{ test };
	  }
    
   sub testPrint {
	print __PACKAGE__ .": The variable \$test is \"$test\".\n";
   }
    
   print __PACKAGE__ .": \$test initialize to the value \"$test\".\n";
   1;

 本来 $test はレキシカルな変数のため外部からアクセスできない。呼び出す側から値を操作することはできないが,モジュール内で初期化時に値を ${^_INITABLini} 変数から取り込んで設定している。

 呼び出す側は,INITABL の require 宣言前に変数 ${^_INITABLini} にハッシュの参照を置き,その {test} に設定したい値を入れておく。

▼ 上記モジュールを呼び出す側(main)
   BEGIN { local ${^_INITABLini}={ test=>"Ok!" };
	  require INITABL;
   }
    
	INITABL::test();
▼ 実行結果(result)
   INITABL: $test initialize to the value "Ok!".
   INITABL: The variable $test is "Ok!".

 実行結果の1行めは BEGIN { …… } 中の require 宣言で呼び出された時に印字されたもので,この時点で既にレキシカル変数 $test に呼び出した側で指定した値が設定できていることを意味する。2行めは呼び出す側5行めの INITABL::test() によって印字されたもの。

 この“^_”で始まる変数を使う方法なら,require 宣言時にカスタマイズした初期化をすることが可能と思われる。

● “^_”を使わなくても読めるケース(2021-12-21 追記)

 その後いろいろ調べたところ,“^_”タイプの変数を使わなくても,モジュール内で変数に設定した値が(MODULE:: を付けずに)呼び出した側で読める場合があることが判明。ただし以下の条件を満たす場合。

◆ 初期化したいなら BEGIN 内

 あるモジュールを use や BEGIN { require …… } などの優先処理宣言で呼び出した場合,宣言よりも前に記載されている処理でも後回しになる。そのため,ある変数に適切な値を調べて設定するモジュールがあったとして,それより前に「デフォルト値を設定しておく」つもりで代入処理を置いても,優先処理宣言されたモジュール内の値の設定が先で,use や BEGIN 宣言の前に記述された「デフォルト値」の設定処理は後になる。結果的に前に記述された「デフォルト値」設定のまま変化しないように見える。呼び出す側で「デフォルト値」を指定したい時は「BEGIN の中で代入処理する」のが適切と思われる。
 一方で,BEGIN { …… } 内に入れずに require 宣言で呼び出すと,宣言より前に使われていた変数もモジュール内でアクセスできる。

 なお use では,こうした「宣言直前の代入処理」などはできない。

◆ use 宣言は BEGIN 内に置かないほうがいい

 どうやら BEGIN 処理の中に use があった場合も,やはりそちらを先に処理するよう。たとえば BEGIN 処理中,$HOME をホームディレクトリ("/home/username")に設定した直後に use lib "$HOME/lib/perl" という処理を置いても,$HOME に値が設定される前に use が処理されるため,@INC には "/home/username/lib/perl" ではなく "/lib/perl" が追加される。BEGIN の外に出すことで記述順通りの処理になるよう。または,BEGIN 内では use lib ではなく unshift @INC, ... を使う。



© M.Ishikawa; TREEWARE 2022.