2018/07/18にNamespace Visiblity for Class, Interface and TraitというRFCが提出されました。
フレームワークやライブラリなどの開発者にとってはわりかし便利そうなRFCだったので紹介してみます。
Namespace Visiblity for Class
Proposal
どんな内容かというと、まあ↓のとおりです。
namespace HOGE{
public class A{}
protected class B{}
private class C{}
}
namespace{
new \HOGE\A(); // OK
new \HOGE\B(); // 死
new \HOGE\C(); // 死
}
class内のfunctionにアクセス修正子を付けられるのと同様、namespace内のclassにアクセス修正子を付けられるようにします。
public
publicクラスはどのnamespaceからでも見ることができるクラスです。
可視性を設定していないクラスはpublic扱いとなります。
要するに今までのclassと同じものです。
private
privateクラスは同じnamespaceからしか見ることができないクラスです。
内部でしか使用しない、外に出す必要がないクラスはここに隠蔽することになるでしょう。
まあprivateメソッド、プロパティと同じ使い方です。
protected
protectedクラスは、同じか、それ以下のnamespaceから見ることができるクラスです。
namespace HOGE\FOO{
protected class A{}
}
namespace HOGE\FOO\BAR{
new \HOGE\FOO\A(); // OK
}
namespace HOGE\BAZ{
new \HOGE\A(); // NG
}
直接的にextendsしているわけではありませんが、protectedなメソッド・プロパティと似たような可視性ということです。
Interface / Trait
クラスだけではなく、interfaceとtraitにもアクセス修正子を書くことができます。
namespace Example {
public interface A{}
protected interface B{}
private interface C{}
public trait D{}
protected trait E{}
private trait F{}
}
namespace Example\Nested{
class W implements \Example\A{} // OK
class X implements \Example\B{} // OK
class Y implements \Example\C{} // NG
class Z{
use \Example\D; // OK
use \Example\E; // OK
use \Example\F; // NG
}
}
上のサンプルでExample\Nested
はExample
のサブnamespaceなので、Example
のprotectedクラスを見ることができますが、無関係なnamespaceからprotectedなinterfaceやtraitを見ようとすると当然NGになります。
privateクラスを覗く
クラスの場合は同名のクラスを作れないのでprivateを直接見ることはできませんが、namespaceは作れるので、やろうと思えば簡単にprivateクラスの中身を見ることができてしまいそうです。
namespace Vendor\Library{
private class DontTouch{}
}
namespace Vendor\Library{
// 見れる?
$class = new \Vendor\Library\DontTouch();
}
これについてはどうなるのか探してみたのですが、特に記述がないようです。
もっともPHPの場合はprivateを見る方法なんていくらでも存在するので、多少抜け道があったとしても、それを見る開発者に意味が伝わればいいという方向でかまわないと思います。
歴史
このRFCに関する最も古い話題は、なんと2007年12月12日の投稿です。
PHPでnamespaceがサポートされたのが2009年のPHP5.3なので、どれだけ早いんだよってかんじですね。
もっとも上記は正確にはnamespace自体の提案で、アクセス修正子については話のついでではありますが。
namespaceの実装後も関連の話題は断続的に出され、2015年にはプルリクも出されていました。
ただこのときは、仕様や実装の考慮不足など問題が色々と発生して、最終的には却下されてしまいました。
はたして今回はどうなるでしょうか。
というかRFCから現行MLやPRへのリンクが貼ってないから、何処で話がついてるのかわらかん。
Redditでいいんじゃろか。
感想
あれば便利だとは思うけど、自分から使うかといったら使わなさそう。
というか前から思ってるんだけど、namespaceってだいたい二重にできるpartial classだよね。