Objectに動的にプロパティを追加する

object 生成後に、宣言とか関数とか使わずにプロパティを追加できるらしい。


by PHP 5.2.6 (Mac OSX)

<?php
class Test {
  public $a = 'default';
}
$test = new Test();
$test->foo = 'bar'; // add property

print_r(get_class_vars('Test'));
print_r(get_object_vars($test));
// 実行結果
Array
(
    [a] => default
)
Array
(
    [a] => default
    [foo] => bar
)


うかつに使うと後から追うのが難しいなーなんて思ってたら、こんなこともできた

<?php
class Test {
  public $a = 'default';
}
$test = new Test();
$hoge = 'hage';
$test->$hoge = 'moga'; // add property
 
print_r(get_class_vars('Test'));
print_r(get_object_vars($test));
// 実行結果
Array
(
    [a] => default
)
Array
(
    [a] => default
    [hage] => moga
)

変数内の文字列の名前を持ったプロパティが追加されている。
ORマッパーを作るなどする時は便利そうだ、が・・・

こんなにさりげないと、あっという間にミートソースをぶっかけたくなりそうで困る。

こんなネタも

PHP 5.4 RC1リリース、新機能の「行番号」や「LIST」「RUN」に注目 : bogusnews
現実はネタよりも奇なり、になる・・・かも。

public なメソッドを private でオーバーライドした場合

Java だと確か、アクセス制限を弱める方向でオーバーライドできた覚えがある。
PHPRuby で同じことを試す機会があったのでメモ。

PHP の場合

Error になる。public なメソッドは public でないといけないらしい。
Java と似た方式。

<?php
class AbsTest {
  public function foo() {
    echo "foo";
  }
}

class Test extends AbsTest {
  private function foo() {
    echo "foo!";
  }

  public function bar() {
    self::foo();
  }
}

$a = new Test();
$a->bar();
// Fatal error: Access level to Test::foo() must be public (as in class AbsTest) 

Ruby の場合

アクセスを厳しくしてもOK。

#!/usr/bin/env ruby
#-*- coding:utf-8 -*-
class AbsTest
  def foo
    puts "foo"
  end
end

class Test < AbsTest
  def bar
    foo
  end
  
  private
  def foo
    puts "bar!"
  end
end

a = Test.new
a.bar #=> bar!

ちなみに Ruby のアクセス修飾子について

ちょっと調べてみたら、Ruby のアクセス制限はちょっと変わってるようだ。
以下引用。

public

そのメソッドが定義されたクラス内、サブクラス、クラス外(インスタンス)のどこからでもアクセス可能です。

private

メソッドは、クラスの内部(定義クラスとサブクラス)からのみアクセス可能。
レシーバを指定して呼び出すのは不可で、クラス内部からでもインスタンスメソッドとしては使えない。

protected

メソッドは、クラスの内部(定義クラスとサブクラス)からのみアクセス可能。
レシーバを指定して呼び出すことができ、クラス内部からであればインスタンスメソッドとして使える。

クラス定義でメソッドへのアクセス制限・public, private, protected by Ruby入門勉強ルーム

なるほどー。

FizzBuzzというかナベアツ

せっかくRubyやりだしたので

FizzBuzzしてみる。
3の倍数でFizz、5の倍数でBuzz、両方ならFizzBuzzを出力。

(1..100).each{|n| p n%3==0||n%5==0?n%3==0?n%5==0?'FizzBuzz':'Buzz':'Fizz':n}

ついでにNabeatsuもしてみる

3の倍数と3がつくときにアホになり(23〜〜〜)、8の倍数のときに気持ちよくなる(16ぅぅういぇぇえぁ)。両方のときは以下略。

(1..40).each{|n| puts n.to_s+(n%3==0||(/3/=~n.to_s)?"〜〜〜":"")+(n%8==0?"ぅぅういぇぇえぁ":"")}

血迷ってPHPでもやってみる

RubyよりわからないPHPでも書いてみる。正規表現がわからんかった。

<?
for($i=1; $i<41; $i++) {echo $i.(if($i%3==0||ereg('3', $i)){"〜〜〜"}).($i%8==0?"ぅぅういぇぇえぁ":"")."\n";}
?>

出力結果

1
2
3〜〜〜
4
5
6〜〜〜
7
8ぅぅういぇぇえぁ
9〜〜〜
10
11
12〜〜〜
13〜〜〜
14
15〜〜〜
16ぅぅういぇぇえぁ
17
18〜〜〜
19
20
21〜〜〜
22
23〜〜〜
24〜〜〜ぅぅういぇぇえぁ
25
26
27〜〜〜
28
29
30〜〜〜
31〜〜〜
32〜〜〜ぅぅういぇぇえぁ
33〜〜〜
34〜〜〜
35〜〜〜
36〜〜〜
37〜〜〜
38〜〜〜
39〜〜〜
40ぅぅういぇぇえぁ

さ、仕事仕事。


参考:日本野望の会−Yabooo.org ? FizzBuzzはもう古い!世界のナベアツ問題。