さて、問題です。
さて
クラスの
アクセス修飾子に
不満を持っていませんか?
私は不満があります。
アクセス修飾子
なんで、
どの言語も
この3つぐらいしか
ないんでしょうか。
今日は、
オブジェクト指向/カプセル化の
幹線にあえて切り込んでみたい。
なんか、めんどっちいですよね。
これではカプセル化が
壊れてしまう。
//確かにコレはできる。
echo $HumanObject->Age;
//しかし、
//今度は、クラスの外から
//書き込まれてしまう。
$HumanObject->Age = 100;
クラスの外から
読めるけど書けない
そんなアクセス修飾子が
ほしい
そんなわけで
作ってみた。
クラス外から クラス内から 継承した場合
読み 書き 読み 書き
public ○ ○ ○ ○ 継承される
niigata ○ × ○ ○ 継承されない
protected × × ○ ○ 継承される
private × × ○ ○ 継承されない
いいですか?
読めるけど書けない
新潟の人ごめんなさい
Fatal error: Cannot access niigata property Human::$Age in /home/rti/lab/php-5.3.2/a.php on line 13
これからは新潟だ!!
新潟アクセス修飾子のご提案
~課題~
class Human
{
private $Age ,$Name, $Address, $Tel;
public function __get( $key )
{
return isset( $this->$key ) ? $this->$key : NULL;
}
};
Q7.外人に
どう説明するの?
A7.ごめんなさい
にいがた
漢字で正確に書いてください。
がたの右上は白ぢゃないよ。
ちなみに私はかけませんw
新潟アクセス
修飾子/指定子のご提案
新潟
という漢字は、
新潟
伯爵認定書
新潟 ==
読めるけど書けなーい
読めるけど、
書けない。
@super_rti
by rti
第二次大戦の要塞後を占拠して独立宣言。
自称国家。
現在、人口4人。
爵位販売中
Lord of Sealand
シーランド公国伯爵
イギリス
肩書き
ハンドル:rti
なんと読みますか?
http://d.hatena.ne.jp/rti7743/
自己紹介
シーランド公国について
ラーメンズ
不思議の国のニポンより
http://rtilabs.net/
後半の
実装部に続く
よく getter を作ってませんか?
今は
宇宙の法則すら乱れる時代。
定番の役割
クラスの外から
メンバ変数を取得するには、
getterを経由して
アクセスしなければいけない。
クラス外から クラス内から 継承した場合
読み 書き 読み 書き
public ○ ○ ○ ○ 継承される
protected × × ○ ○ 継承される
private × × ○ ○ 継承されない
public protected private
新潟アクセス修飾子のご提案
~問題提起~
class Human{
private $Age;
public function
__construct($age,$name){
$this->Age = $age;
//略
}
//年齢を取得する.
public fnction getAge(){
return $this->Age;
}
};
//Ageを取るにこうする必要がある。
echo $HumanObject->getAge();
これを変えようという人を
見たことがありません。
神が創った宇宙の法則でもないのに。
なぜ固持するか!
メンバ変数を外から読むために
よく使いますよね?
アナログ
//Ageを取るにこうする必要がある。
echo $HumanObject->getAge();
嘘です。
比較
//コレできても、
echo $HumanObject->Age;
//これはできないでほしい
$HumanObject->Age = 100;
class Human{
//private $Age;
//↓
public $Age;
public function
__construct($age,$name)
{
$this->Age = $age;
//略
}
//年齢を取得する.
public fnction getAge(){
return $this->Age;
}
};
//私は、こうやりたい。
echo $HumanObject->Age;
コレは困った。
パッチをダウンロードする
#ダウンロード
#php 5.3.2 本体
wget http://jp2.php.net/distributions/php-5.3.2.tar.gz
#新潟パッチ
wget http://rtilabs.net/files/2010_05_20/niigata.patch
#サンプルその1とその2
wget http://rtilabs.net/files/2010_05_20/niigata_test1.php.txt
wget http://rtilabs.net/files/2010_05_20/niigata_test2.php.txt
誰がどうみても
クラス外から クラス内から 継承した場合
読み 書き 読み 書き
public ○ ○ ○ ○ 継承される
protected × × ○ ○ 継承される
private × × ○ ○ 継承されない
新潟だ
つまり、niigataは
クラスの外から
パッチの適応
新潟アクセス修飾子のご提案
~ご提案内容~
php 5.3.2 の
Zendエンジンを改造して
新潟アクセス修飾子を実装
public , protected , private , niigata
新潟
##パッチを当てる
#パッチ当てるのがめんどくさい人にはパッチを当てたバージョンもあるよ!
#http://rtilabs.net/files/2010_05_20/php-5.3.2.niigata.tar.gz
#
patch < niigata.patch
##余談
##diffはこうやって作った。
##diff -crN php-5.3.2 php-5.3.2_niigata > niigata.patch
読めるけど、
書けない!!
パッチを公開中
新潟!?
読めるけど、書けない!!
新潟!!
コンパイルして遊ぶ
新潟 in php 5.3.2
#コンパイル
cd php-5.3.2
./configure
make
##サンプルで遊ぶ
#書き込み失敗のサンプル
./sapi/cli/php ../niigata_test1.php.txt
#読み込めることを確認するサンプル
./sapi/cli/php ../niigata_test2.php.txt
class Human{
niigata $Age;
public function
__construct($age,$name)
{
$this->Age = $age;
//略
}
};
//クラスの外から読める
echo $HumanObject->Age;
//だけどクラスの外から書けない
$HumanObject->Age = 100;
無意味なgetterが
消えてすっきり!
比べてください
Q3.スレッドセーフは?
Q1.新潟のメソッドは
どうするか?
Q2.protectedな
新潟が欲しい。
Q4.__getでできるよ?
Q5.パフォーマンスコスト
class Human{
niigata $Age,$Name,$Address,$Tel;
public function
__construct($age,$name)
{
$this->Age = $age;
//略
}
};
Q6.php以外の
他の言語の対応は?
class Human{
private $Age,$Name,$Address,$Tel;
public function
__construct($age,$name)
{
$this->Age = $age;
//略
}
public function getAge(){
return $this->Age;
}
public function getName(){
return $this->Name;
}
public function getAddress(){
return $this->Address;
}
public function getTel(){
return $this->Tel;
}
};
php 5.1以上なら
__getで作れば
同じことできるよ。
javaでいう
synchronizedは
どうすんの?
継承して使いたい。
class Human
{
//どうしよう。。。
niigata function song()
{
}
};
新潟の拡張で
既存のプログラムが遅くならない?
C++とかjavaでもniigataしたい。
5・7・5
通常
新潟
新潟 is very difficult.
bad read easy...?
しかも、
カプセル化は破壊されない!
A2.今は無理です。
通じるかー
A3.そんなの関係ねー
A5.あんまり遅くないですよ
A1.未サポートです。
A4.そ、そうですね。。。
A6.そのうちやるかもよ!!
新潟に不利なカウントテスト
1000000万回
private の拡張として実装。
final ような立ち居地で
独立させるべきかも。
niigata private
niigata protected
みたいな。
<?php
class Counter
{
public $count = 0;
}
$p = new Counter;
for($i = 0 ; $i < 1000000 ; $i ++ )
{
$p->count ++;
}
echo $p->count . "<br>\r\n";
phpにはスレッドはない。
仮にあったとしても、
スレッドセーフにするのは
個々のクラスの
責任ではない。
上位の専用のクラスの責任である。
そこはgetterで書けばよい。
言語仕様として組み込めれば、
作らなくてもOKです。
ソースコードを見ただけで
どれが外部から読みだされるか
簡単に分かります。
また、パフォーマンスも
ネイティヴで書いているので、
__getより5倍ぐらい早いです。
現在サポートしていません。
private と同じになります。
C++でいう
const メソッドにしたい。
無意味な
getterからの解放
そして、
時代は、
getterから
新潟へ
オリジナル php
新潟 php
コレをするにはもっと改造が必要
新潟(niigata)
すげぇぇーー!!
http://ml.php.gr.jp/pipermail/php-dev/2010-May/thread.html
time sh test.sh
real 0m0.130s
user 0m0.117s
sys 0m0.012s
time sh test.sh
real 0m0.130s
user 0m0.117s
sys 0m0.014s
それ C# でできるよ!
それ ruby でできるよ!
ruby
niigata
C#
niigata
class myClass
attr_reader :Age
end
class myClass
{
niigata $Age;
}
class myClass
{
public int Age
{ get; private set; }
}
31bytes
27bytes
good!
新潟の方がタイプ数が少ない。
アクセス修飾子を見ただけでわかる。
トータルのタイプ数だとまだ新潟の方が少ないが、rubyはすごいですね。。。