その他の翻訳 > github.com


この文書は PPCs/ppcs /ppc0018-module-true.md を翻訳したものです。

原題は「No Longer Require a True Value at the End of a Module」です。

Preamble 序文


Author:  Curtis "Ovid" Poe <curtis.poe@gmail.com>
ID:      0018
Status:  Draft

Abstract 要約

This PPC proposes a feature which, when used, eliminates the need to end a Perl module with the conventional "1" or other true value.

このPPC提案は、Perlのモジュールの末尾を伝統的に "1" や他の真の値で終わらせる必要をなくすものです。

Motivation 動機

Eliminate the need for a true value at the end of a Perl file.


Rationale 提案理由

There's no need to have a true value be hard-coded in our files that we `use`. Further, newer programmers can get confused because sometimes code _doesn't_ end with a true value but nonetheless compiles just fine because _something_ in the code returned a true value and the code compiles as a side-effect.

use するときに、ファイルに真値をハードコードする必要性はありません。さらに、新参者の プログラマーは真値でコードが 終了しない にもかかわらず、真値を返す なにかしら が 副作用でコードをコンパイルできてしまうことで混乱します。

Specification 仕様

First, a new `feature` is added:

まず、新しい feature が追加されます:

use feature 'module_true';
Then, *whenever* a module is loaded with `require` (or an equivalent, like `use`), the "croak if false" test is skipped if the `module_true` feature was in effect at the last statement executed in the required module.

そうして、require (あるいは同等の use など)でモジュールがロードされた時は いつでも、requireされたモジュール内で実行されている最後のステートメントでmodule_trueフィーチャーが 有効ならば、"croak if false(偽ならcroakする)"テストをスキップします。

Backwards Compatibility 後方互換性

There are no compatibility concerns I'm aware of because we're only suggesting changing behaviour in the presence of a newly-added feature that is not present in any existing code.

私の気づく範囲で互換性の問題はありません。なぜなら既存のコードにはない新しいfeatureを追加して 振る舞いを変えることを提案しているにすぎないからです。

Security Implications セキュリティ懸念

None expected.



Imagine this module:


package Demo1;
use feature 'module_true';

sub import {
  warn "You imported a module!\n";
When loaded by `require` or `use` anywhere in perl, this would import successfully, despite the lack of a true value at the end. This module shows an (almost certainly never useful) way to croak anyway:

perlのどこでもrequireまたはuseによってロードされる時、このインポートは成功し、 末尾の真値がなくても関係ありません。


package Demo2;
use feature 'module_true';

return 1 if $main::test_1;
return 0 if $main::test_2;

  no feature 'module_true';
  return 0 if $main::test_3;
In this example, the only case in which requiring Demo2 would fail is if `$main::test_3` was true. The previous `return 0 if $main::test_2` would still be within the scope of the `module_true` feature, so the return value would be ignored. When `0` is returned outside the effect of `module_true`, though, the old behavior of testing the return value is back in effect.

こちらの例では、Demo2のrequireが失敗する唯一のケースは、$main::test_3 が真のときです。 すぐ前の return 0 if $main::test_2 では、依然として module_true feature のスコープの 範囲内なので、戻り値は無視されます。しかし、module_true の効果の範囲外で 0 が返される時、 古い振る舞いである戻り値のチェック機能が復帰します。

Prototype Implementation 試験実装

There is a prototype implementation at [true](https://metacpan.org/pod/true).

試験実装はこちらです。 true

Future Scope 今後の展望

Due to this being a named feature, this can eventually be the default behavior when `use v5.XX;` is used.

名前付きfeatureになるので、use v5.XX; が使用された時のデフォルトの挙動に含まれることになります。

Rejected Ideas 却下された案

It's been discussed that we should return the package name instead. This supports:


my $obj = (require Some::Object::Class)->new;
However, per haarg:


> Changing the return value of require seems like a separate issue from what > this PPC wants to address. > > If you wanted require to always return the same value, and for that value to > come from the file, you need a new location to store these values. This > would probably mean a new superglobal to go along with %INC. And it would > usually be useless because most modules return 1. I don't think this is a > very good idea. > > If you wanted require to always return the package name, it's a separate > issue from this PPC because that means ignoring the return value from the > file. It also presents a problem because require doesn't actually take > package names. It takes file path fragments. Foo::Bar is translated to > "Foo/Bar.pm" at parse time. This would then need to be converted back to a > package name, or do something else. I don't think this is a good idea > either. > > Instead, it's probably best addressed with a builtin::load or similar > routine that accepts a package as a string. This has been discussed in the > past, and solves other problems. Module::Runtime has a use_module function > that behaves like this, returning the package name.


もしつねにrequireが同じ値を返すのを望み、その値がファイルから来るのなら、その値を 保存する別の場所が必要です。これはおそらく %INCと共に新たなスーパーグローバルな変数で あることを意味します。ほとんどのモジュールは1を返すので、そのようなものは大抵不要です。 私は良いアイディアだとは思いません。

もしつねに"require"がパッケージ名を返すように望むなら、このPPCとは別の問題です。 なぜならファイルからの戻り値を無視することを意味するからです。requireは実際は パッケージ名をとらないので、問題も生じます。それはファイルパスの断片を取得します。 Foo::Bar は、パース時に "Foo/Bar.pm" に翻訳されます。そうしてこれはパッケージ名に 戻される必要があるか、その他の場合もあります。いずれにしろ良い考えではないと思います。

代わりに、builtin::load あるいはそれと同様のパッケージを文字列として受け入れる サブルーチンで対処するのがおそらく最善でしょう。過去に議論されてきたことであり、 他の問題を解決もします。Module::Runtime はこのように振る舞う use_module関数を 持っていて、パッケージ名を返します。

Thus, we prefer simply returning `true` (or `1`).

そうして、我々は単に true (または1)を返すことを選びました。


Copyright (C) 2022, Curtis "Ovid" Poe

This document and code and documentation within it may be used, redistributed and/or modified under the same terms as Perl itself.