gorogoroyasu

福岡の開発会社で働いている。

Maximum function nesting level of '256' reached, aborting!

タイトルのエラーが発生したので原因を調べた。

何を言ってるかよくわからなかったので、ググった。

参考サイト1
参考サイト2

発生状況とかを書いておこうと思う。

CakePHP3 を使用 HogeBehavior.php を 読み込んだ。

UsersTable.php

public function initialize ()
{
    parent::initialize();
    $this->addBehavior('Hoge');
}
// 続きのコード

そして、 HogeBehavior.php の中に問題があった。

use Cake\ORM\TableRegistry;

public initialize ()
{
    parent::initialize();
    $this->Users = TableRegistry::get('Users');
}

Users から読み出す HogeBehavior.php の中で
TableRegistry::get('User') をしていたのだ。

原因がわかったので一件落着。

結論

UserTable から読み込む Behavior の中で TableRegistry::get('User'); をしてはいけない。

原因調査 だが、せっかくなので事故原因を調査してみた。
vendor の中を読む。

まず、use \Cake\ORM\TableRegistryとあるので、 TableRegistry の中を読みに行った。

すると、public static function get($alias, array $options = [])という メソッドが見つかった。

このメソッドは、static::locator()->get($alias, $options) をreturn している。
そして、この return の前で error が出ているらしかったので、更に深く潜った。

ところで、

return static::locator()->get($alias, $options);

という書き方は、遅延静的束縛というらしい。 このクラスを継承しているクラスのオブジェクトからこのメソッドが呼ばれた場合、 継承先のlocator()を読み込むという書き方らしい。(説明が難しいし微妙に違いそう。)

しかし、今回は直接このクラスを呼んでいるので、

return self::locator()->get($alias, $options);

と等価だ。(と思う)

ということで、 \Cake\ORM\TableRegistry クラスの中の

public static function locator(LocatorInterface $locator = null)

を呼んでいる。

このクラスの返り値は

static::$_locator;  

であり、ありがたいことにコメントで

* @var \Cake\ORM\Locator\LocatorInterface  

とある。

つまり、

Cake\ORM\Locator\TableLocator

が返ってくる。
すなわち、

return static::locator()->get($alias, $options);

の中の

static::locator() = Cake\ORM\Locator\TableLocator

となる。

そこで、Cake\ORM\Locator\TableLocatorクラスのget()メソッドを探しに行った。

この、179行目、

$this->_instances[$alias] = $this->_create($options);

で呼んでいる、

protected function _create(array $options)

が今回のエラーの原因だった。

このメソッドの中で

return new $options['className']($options);

という風に
$options['className']($options) を繰り返し new して返している。
ここがポイントだった。

つまり、

TableRegistry::get('User');

により、UsersTable クラスのオブジェクトが生成される。 そして、UsersTable クラスの

public function initialize() 

が動き、もう一度

$this->addBehavior('Hoge');

が呼ばれる。 そして、TableRegistry が動きまたUsersTable クラスが new される。

この繰り返しが256回おこり、 参考サイト1 に書いてあるエラーが起こったのだった。

これが事故原因。

解決方法は、

Cake\ORM\TableRegistry

の使い方に気をつける。

という話でした。

vendor の中見るのたのしー!

感想

なんか、全体的に感想文みたいになってしまったが、
vendor の中を見るのがこんなに楽しいとは思わなかった。
これからも継続して読んでみようと思う。

今時の若いもんは、Windows10をクリーンインストールしてCentOS5.5をインストールすることもできんのか。

今時の若いもんは。。。

今時の若いもんは、vagrant とか docker とか使って楽ばっかりしよってから。 なっとらんばい。

ということで、福岡県で働いています。 今日も福岡は平和です。

さて、表題のとおりですが、色々あってWindows10 がプリインストールされたマシンをクリーンインストールして、CentOS5.5 を入れようという話になりました。 で、弊社の新人が担当することになりました。

しかしこの世代、ゆとりゆとりと言われていますが、まさかここまでひどいとはね。 まさかCentOS入れるのに5時間もかかるとはね。 がっかりですよ。今時の若いもんは。。

という声が聞こえて来そうな大失態を犯した新卒が僕です。 いやー。辛かった。

ということで、表題どおりですが、今日業務でWindows10がプリインストールされたマシンにCentOS5.5を入れました。

僕は、大学時代ゲームをやってたので、SSD 買ってきてWindows インストールとか時々やってました。 だから、余裕だと思っていました。

え? Windows10 って、Daemon Tool 使わなくていいんでしょ?楽勝じゃないすか?www ぐらいののりでした。

仕事をなめてます。はい。少なくとも今日に関しては。。。

ということで、ハマった話です。

CentOS5.5 ってどっから入手できるんだっけ?

最初のハマリポイントは、OSの入手方法です。 実は、以前 http://blog.fusic.co.jp/archives/3796/ を参考に、CentOS6.6 を使ってvagrant box を作ったことがありました。 だから、isoとかいうファイルをネットからダウンロードしてくればいいんでしょ?楽勝ですね! って言う感じでした。

ところが、

という感じで、どこにも置いてないんですね。 どこも、Readme だけのもぬけの殻。

http://qiita.com/timothy_o/items/d7d7b8de23b426eddf2f をみつけて探してみても、 http://archive.kernel.org/centos-vault/5.5/isos/x86_64/ liveDVD.iso がない。

詰みです。

先輩に泣きつきました。

すると、 倉庫から、秘伝の"CentOS5.5が入ったDVD"が出てきたのです。 驚きました。喜びました。 道端で1万円もらった気分でした。 もらったことないけど。

ということで、無事、インストールディスクも見つかりました。 さて、仕事開始です!

人生はそんなに甘くない。

DVD も手に入れたし、あとはBios を立ち上げてドライブ起動順を切り替えれば終わり♪ と、意気揚々とスキップしながら倉庫から出てきました。

BIOS の設定で、SafeMode なるものがあったので、一応disable にし、 UEFI モード とかいう設定をオフにしました。 そして、起動順を切り替えました。

そのまま、設定を保存すると、画面には、 Welcome To CentOS と書いてあるではないですか! 僕の喜びは絶頂です。 仕事ってこんなに楽で良かったんだっけ? って思いながらほいほい次へ進みました。

しかし、そのときはやってきました。

全てのパーティションを削除して上書きする(英語は忘れた)的なやつに "はい" と押す。 その後、 "ほんと?" と聞かれたので、"はい"を押しました。 すると、 設定とかいじる? と聞かれたので、 "はい" を押しました。

そして、なんかでかい画面が出てきました。

エラー!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! f:id:adiboy:20160930230108j:plain

だとさ。 解決方法はqiitaにあげてます。

http://qiita.com/gorogoroyasu/items/117d85938a60cdb269de

疲れたのでこの辺で。

何が言いたいの?

もっとサーバーに詳しくならなくてはならないなと反省しました。 LPIC の本買ったんで、読みます。 しかし、CentOS5系とか、これから先触ることがあるのだろうか。。。

CakePHP3のガラケー対応プラグイン作った!その名も Garak!

僕のスマホ遍歴

突然だが、僕のスマホ遍歴の話をしようと思う。
僕は、2011年までガラケーを使っていた。
最初のスマホは、 iPhone4Sだった。
それからかれこれ5年間。
ずっとスマホを使い続けている。
僕のスマホ遍歴はこんな感じ。

iPhone 4S  
iPhone 4 (4Sがアスファルトに直撃して画面が全壊したのでヤフオクで購入。この子は最終的に裏面が全壊)  
iPhone 5S  
arrows M02 (あまりに動作が遅く、親に譲った。使用期間半年。)
iPhone SE (←今)

ずっとiPhone を使っていたからAndroid を偵察してみよう! と思って買った arrows M02 が想像以上の遅さで、
これまで以上にiPhone が好きになった。

ちなみに、最後に使ってたガラケーのことはさっぱり覚えてない。

ガラケー対応プラグインの必要性

そんな僕が、ガラケー対応のプラグインを作成した。
理由は、スマホのシェアがそこまで高くないから。
ここにシェアがまとめてある。
www.nikkei.com

その中から抜粋すると、
スマホの普及率 : 67.4%(前年度比6.8ポイント増)
スマホ以外の普及率 : 64.3%(前年度比5.5ポイント減)
という感じ。
(なぜか合計が100% ではないのはご愛嬌)

依然としてガラケーユーザーもいる模様。
(ガラケーでWeb サイトを閲覧する人がどれだけいるのかは別の話。通話はガラケーとかいうめんどくさい選択をしている人もいるし。。。)

しかし、なぜガラケー用のプラグインなるものが必要になるのか?
それは、、、

PC、スマホガラケーでは、色々な違いがあるから。

たくさん違いがあるが、個人的に重要だと思う違いは、
1) 文字コード
2) クッキー使用の可否
3) 外部CSS の読み込み
4) JavaScript 使用の可否
の4つ。
それぞれ簡単に説明していく。

1) 文字コード
最近のPC,スマホサイトには、文字コードは"UTF-8" が採用される。
しかし、ガラケー文字コードは"Shift-JIS" である可能性が高い。
可能性が高いと言っているのは、
携帯キャリア、製造年月によってはUTF-8 が使用できることがあるからだ。
しかし、大事なのは、文字コードは "Shift-JIS" を使った方が安全だということだ。
ということで、全ての文字は、 UTF-8 から Shift-JIS に変換されなくてはならない。
めんどくさい。

2) クッキー使用の可否
基本的に、ガラケーではクッキーを使うことができない。
では、どうやってログイン情報等を管理するか?
URL の末尾にセッションID をつける。
それにより、ログイン情報等を管理する。
実に原始的。めんどくさい。

3) 外部CSS の読み込み ガラケーでは外部CSS が使用できない(ことが多い)。
そのため、CSS を直書きする必要がある。

<div class="hoge" style="color: green;">hoge</div>   

みたいな感じ。
めんどくさい。

4) JavaScript 使用の可否
基本的にガラケーではJS を使うことができない。
悲しい。

と、ざっくり上げただけでも4つの違いがある。
特に面倒くさいのは1) と 2) 。
ここらへん、なんとかしたい!!

作ったプラグイン

ということで、 上記 1) と 2) をいい感じで解決するプラグインを作った。
本当は 3) もなかなかめんどくさいんだけど、
いい感じにテンプレートとか拾ってきて対応して下さいー。

プラグインはcomposer を使って ここ からインストールできます。
名前は、 "Garak" !

ぜひ使ってみて下さい。

と、言いたいけど、
このプラグインが不要になる日を楽しみにしています。

何も考えずに銀歯入れてない?

歯医者で被せ物をした。

 

一般に、被せ物といえば銀歯だ(日本語がおかしいかも)。 笑うと奥の方の歯がシルバーに輝く。それはそれで、嫌いではない。

 

だけど、僕は、白いセラミックスで作られた歯を入れる選択をした。理由は幾つかある。

 

1. 金属を噛んだ時の電流が流れる感じがしないか不安だったから

 

アルミホイルを噛んだ時とかに感じる嫌な感じ。あれが不安だった。噛むたびに嫌な思いをしてたら、食べることが嫌いになってしまうと思う。まあ、大丈夫だとは思うんですけどね。教えて、エロい人!

 

2. 銀歯は、相当枯れた技術であること

 多くのサイトで言及されてるように、銀歯は昔から使われている技術らしい。参考:http://nichigopress.jp/healthcare/healthcare_sodan/29008/

枯れた技術のいいところは、その安定感だ。安定感とは、多くの人がやってるから自分も大丈夫だろうという無責任な安心感のことを指す。でも、銀歯って本当に大丈夫なの?戦後すぐってものが本当に何もなかった頃でしょ?ものをふんだんに使える現在でも、使い続けてる意味って何?そんな疑問を持たずに枯れた技術の侵略を許すのが嫌だった。

 

3. 3Dプリンタを使うって、なんかイマドキっぽいから!

それじゃあ、セラミックスは?要は陶器でしょ?土器を口の中に詰めてるのと何が違うの? まああまり違いはない。でも、3Dプリンタで作るって聞いたら、なんかカッコいいと思ってしまうじゃん!材料を研究してた人として、今回使ったお金が材料研究のお金に使われると嬉しいし、ソフトウェアエンジニアとして、「俺の歯、3Dプリンタで出来てますよ」って言うの、掴みとしてはめっちゃいいと思うし。いいことづくめ!

 

ということで、セラミックスの歯を入れました。理由は全部後付けです。

 

気になるお金の話

正直、お金はかかった。 歯の土台と被せ物で合わせて約6.5万円。かなり高い買い物だ。だけど、いいと思った技術にはお金を払うべきだし、意識改革にも繋がると思うから、高かったとは思ってない。ソニッケアのダイヤモンドクリーンも最近買ったから、歯への投資が最近半端ない。まあ、いい事だと思っておこう。

 

ということで、何も考えずに銀歯を入れるのはどうなの?という話でした。

メール確認ってめんどくさい

メールを送るのって、大変ですよね?

誤字脱字があったら信頼が下がるとか超だるい。

複数の意味に取れる言葉を使うと相手に混乱を与えるけど、自分で読み返しても気づかないことが多いし。

 

そこで考えたのが、メールやドキュメントをチェックするバイトを雇うこと。

 

バイトの人からすると、メールをさらっと読んで分からないところがあったら指摘する、簡単な仕事。逆に、メールを送る人は、無駄な時間を使わなくて済む。メールなんて、即時性はそんなに重要じゃないし。

やりとりをbacklog とかslackにすると、会社に来てもらう必要もない。

これって結構いいアイディアだと思うんだけど、どうですかね?

 

たぶん、メールチェックを外注するのは少し怖いから、バイトの人にやってもらったほうがいいと思うけど。

秘密保持等がうまくできる仕組みができれば、結構流行ると思うんですけどね。そうすると、会社ができたりする。

まあでも、皆が秘密を守ることを前提にしたシステムはいずれ破綻するから、微妙かもな。Twitterとかに社外秘書かれたりしたら損害半端ないし。

来年(今年でも可)の新卒とかに、この仕組みを取り入れてみればいいんじゃないですかね?

実際に社会人が送ってるメールを見る機会なんてそうそうないし、面白いと思うのですが?

対面レビューに参加した話

対面レビューの重要性

僕は、新卒で今の会社に入社した。 ほんの数カ月前まで、全くの未経験だった。

ここ数ヶ月で手取り足取り色々なことを教えて頂き、 本当に楽しい毎日をすごしている。

ところで、今日、同期の対面レビューがあった。 うちの会社のレビューの流れは、
1. コードを書く
2. GitLab で主にチームメートがレビュー
3. 修正する
4. ある程度修正が溜まった段階で、会議室でディスプレイにコードや作ったものを映しながらレビュー

という流れになっている。

僕のレビューは約2週間前にあった。
その時は、結構つっこみが多く、修正するのが大変だった。

そんな思い出もありつつ、今日、同期の対面レビューに参加した。

自分が指摘される側では気づけないことがあると思ったからだ。

そして、気づいたことは、

  • コメントアウトはイラッとする(console.log('hoge');とかも)
  • 適度にスペースを使わないと見づらい
  • 2箇所以上で用いる処理は、メソッドとして切り出す
  • コードレビューはメモを取りながらしてもらう

みたいな感じだ。

コメントアウトはイラッとする

僕も結構コメントアウトを残したままpush してしまうことがある。
だけど、初めてレビューする側に回ってかなり嫌な気持ちになった。
理由は、
- 画面に映せる範囲が限られているので、スクロールしなくてはならなくなる。
- なぜ残っているのかを考えてしまう
だ。他にも何か思った気もするから、思い出したら書く。

適度にスペースを使わないと見づらい

コードを書いているときは、集中しているから、多少見づらくても関係ない。
だが、読む人からすると、少しの見づらさは致命的だ と気づいた。
似たような処理をしている箇所はまとめて、少し毛色が違う処理はスペースを開けるといいと思った。

2箇所以上で用いる処理は、メソッドとして切り出す

これは、同期のコードを見て気づいたことだ。
僕は、2行ぐらいでかけてしまう部分は、わざわざメソッドとして切り出す必要はないと思っていた。
可読性とかあんまり関係ないし。
だが、実際に、メソッドに切り出されたコードを見て、
読みやすいことに気づいた。
これは、即実践しようと思う。

コードレビューはメモを取りながらしてもらう

これは、録音とかでもいいかもしれない。
とりあえず、後で見返せる何かが欲しい。
僕は、コードに直接 // TODO を書いていったが、
TODOは、その箇所を修正したら消してしまう。
見方を変えれば、プロのエンジニアが僕にかけた時間が水の泡になっている。
もちろん、一度言われたことを二度と間違えない人間なら問題無いだろうが、僕は超人ではない。
ということで、今度から対面レビューをしてもらうときはメモを取ろうと思う。

今日学んだことは、こんな感じです。
今日作ってしまった ポンコツAPI の話はまた次回。

ルール

今日は、1ポモドーロ以内!読みなおす時間も少し残っている!素晴らしい!