TypeScript 文句一個垂れます
このコードをコンパイル。
namespace a.b.c { import f1 = e.f; import f2 = b.e.f; import f3 = a.b.e.f; function d() { return f1 + f2 + f3; } } namespace a.b.e { export var f; }
どうなるかというと、
AnasAbdin

@theartofmadeline

No title available
Aqua Utopia|海の底で記憶を紡ぐ
No title available

★

titsay

Love Begins
almost home
TVSTRANGERTHINGS
$LAYYYTER

Product Placement

blake kathryn

oozey mess
🪼

pixel skylines
Three Goblin Art
tumblr dot com
Misplaced Lens Cap
ojovivo

seen from Germany

seen from Austria
seen from United States
seen from Germany

seen from Malaysia
seen from Germany
seen from United States
seen from Germany

seen from United States
seen from United States
seen from United States
seen from United States
seen from United States
seen from United States
seen from United States

seen from United States
seen from United States
seen from United States
seen from United States

seen from United States
@ajimicho-blog
TypeScript 文句一個垂れます
このコードをコンパイル。
namespace a.b.c { import f1 = e.f; import f2 = b.e.f; import f3 = a.b.e.f; function d() { return f1 + f2 + f3; } } namespace a.b.e { export var f; }
どうなるかというと、
VS Code アップデートエラー
Visual Studio Code のアップデートをしようとしたら。謎エラー。
The setup files are corrupted. please obtain a new copy of the program.
面倒で放置していたんだけど、重い腰を上げていっちょ解決してみようかと思ったらネットにいい情報がすぐに見つからなくて、結局自力で解決したので、困ってる人もいるんじゃないかということで、情報流しておく。
Chrome for Android で HTMLのダウンロード
ちょっと入用のために、Android から HTML を気軽にダウンロードできるブックマークレットを作ってみた。
あくまで HTML しかダウンロードしないよ! 埋め込まれた画像とか、外部リソース (CSS ファイル、JS ファイルとか) は一切なし。
ブックマークレットの導入方法なんかは説明され尽くしているのでどこかで調べてほしいんだけど、作ったブックマークレットをご自由にお使いくださいってことでここにおいておくことにする。
そうだなぁ、じゃあライセンスは、 WTFPL ってことで。
JS の bind の polyfill 改良版
また bind の話ですか。
JavaScript の Function.prototype.bind() の polyfill が MDN で紹介されている。
この bind って機能は比較的初期の段階で各ブラウザに実装されてるし、polyfill (実装されていない場合の代替手段みたいなの) が必要なことは少ないんだけど、問題は Android のやつ。
あいつ、一部の古い機種で bind ができない。 驚愕したね。マジかよ、bind ってもっと超標準みたいな扱いかと思ってたよ!
そこで polyfill の出番なんだけど、上に張ったリンク先の polyfill はリンク先にも書かれているように、本物とは幾つか違いがあるらしい。
その違いが問題になりそうな場面に出くわしたので、思いつく限りで修正を加えてみた。
PHP 文字列中の定数の展開っぽいことを実現する
PHPで、変数展開ってあると思うんだけど、あいつは便利で僕も結構使う。
$a = 'world'; echo "Hello, $a";// => 'Hello, ' . $a と同様の出力を得られる
でも定数展開はできない! なぜなら、PHPは "ダブルクオーテーション" の中に $Doller記号 を見つけたら、そこを変数名として扱う。 定数は$を使用しないので展開してもらいようがない。
でも定数を展開したいっていう人は世に多く、ggると色々なやり方がバッドノウハウですと出回っている。 今日はそんな人たちの間に参加してみようと思う!
JSのbindで作られたFunctionのcalleeはbind前のFunction?
↑何言ってんだこいつ。 待って待って。聞いて。
今回はPHPどころかJavaScriptのお話。
JavaScriptにFunction.prototype.bind()ってあるじゃない。 thisを変更するあれ。
あと、arguments.calleeってあるじゃない。 関数から見た自分自身がわかるあれ。
その2つを組み合わせた時の奇妙な動きが気になって朝も起きれないので紹介します。
従来のエディターでは敵うハズのない特徴。テキストエディター「Caret」
どんな環境でもまず絶対使うってソフト、テキストエディターが挙げられる気がするんだけど、技術寄りの人ならかなりの頻度で使うよね。
そしてこだわるよね。
僕はサクラエディタ派だけど、最近はCaretというChromeアプリに浮気中。
というのも、基本性能はサクラエディタに匹敵する上、いくつかの点でサクラエディタを上回っていると思う。
いくつか特徴を紹介。サクラエディタを愛用してきたもので、サクラエディタとの比較っぽくなっちゃうけど。
かっこいい
重要だよね。やっぱかっこいいエディターでモチベーション上げていきたいじゃない!
ご覧ください。用意されているテーマの中でワタクシが気に入った配色でございます。
言い訳
CakePHP3安定版もリリースされてしばらく経ったけど、実はちょっとCakePHPを使った作業から離れてるという感じです。こんにちは。
安定版じゃないからバグってるよーとか書いたけど安定版で直っているかも確認できていません。誰か教えて!
気が向いたらCakePHP以外の技術系の記事を書くかもしれません。今日早速もう一個書きたいと思います。
更に気が向いたら、最終的には分けるかも。ブログを分けるか、カテゴリを分けてCakeじゃないブログに。
っていう、この投稿は何だったのかというとタイトルが全て。
CakePHPのアソシエーション設定時、'foreignKey' => falseが正しく処理されない
CakePHP 3.0.0 RC-1で起こっている。まぁ、安定版じゃないもんねぇ。
たぶん、一緒にconditionsを指定して独自の条件でアソシエーションを定義したいとき、勝手に外部キーを使われると邪魔くさいのでオフにしたい場合に使うことが多いだろう。
生成されたSQLを見る限り、where条件で`カラム名` = (ここに何も入らない)となってシンタックスエラー。勝手に生成されたSQLがシンタックス面で怒られてしまうというのはやっぱりフレームワークのバグなんだと思う。
'foreignKey'=>falseは安定版リリース後に使うとして、暫定対応としてはエンティティーにゲッターを定義することだろうか。
必要最低限の修正にするため、エラーの起こらないカラム名をforeignKeyに指定しておく。アソシエーション自体を消してしまうと、find時にアソシエーションがないっていうエラーが発生するので。 そうすると今度は余計なwhere条件が追加され、自分の想定したレコードが取ってこられない。
そこでエンティティークラスにアクセッサーを定義して、想定していないアソシエーションを無視した結果セットを取得しなおす。
アクセッサーの定義方法は以下。 http://book.cakephp.org/3.0/en/orm/entities.html#accessors-mutators
Lazy Loadingの解説も参照。 http://book.cakephp.org/3.0/en/orm/entities.html#lazy-load-associations というかやってることはまんまLazy Loading。
要は、_getXxxというゲッターメソッドを定義すれば、$entity->xxxというプロパティを参照しようとしたときに、実際に持っているxxxの値ではなくて_getXxxの戻り値が参照される。
_getXxxの中で、お好きなfindを実行すればOK。
ちなみにフォームヘルパーなど、持っている値を直接見に行ってしまう奴らにエンティティーを渡した際に、想定していない動きになる可能性があるので注意。 (注意ったってこっちはフォームヘルパーをオーバーライドして回避する程度の力技しか思いつかなかったけど)
バグが修正されたら、ちゃんと'foreignKey'=>falseに書き換える。 そしてエンティティーに作ったゲッターを削除する。これをやらないと結局ゲッターが優先されるので忘れずに。
CakePHPの入力欄が自動でカラムに紐づかない時に疑うこと
Formヘルパーで出力するフォーム系のinputやらselectやらtextareaやらの入力欄。 規定ではデータベースのカラムの型やカラム名に応じた形で自動的に出力されるけど、うまいこと設定されない場合は全部input type="text"で出力される。 何が原因でうまいこと設定されていないのか、疑うべきチェックポイント。
エンティティーを渡し(せ)ていない
アソシエーションが正しくない
この2点を疑ってみて。
エンティティーを渡し(せ)ていない
CakePHP2を使ったことがある場合に1回くらい引っかかるかもしれない問題。
CakePHP2の場合、
<?=$this->Form->create('User')?>
のように、テーブル名を渡してフォームを開始していた。 でもCakePHP3では、エンティティーを渡すことになっている。
<?=this->Form->create($user)?>
もちろん、その前にコントローラー側でビューに渡す変数としてエンティティーを用意しなければいけない。
// リクエストデータからユーザーエンティティーを作成 $user = $this->Users->newEntity ( $this->request->data ); // ユーザーエンティティーをビューに渡す $this->set('user', $user);
リクエストデータ?なにそれ。 例えば、ユーザーが全ての入力を完了して送信ボタンを押したけど、サーバー側でバリデーションをした結果入力エラーとなったため、エラーメッセージを出して再入力を促す場合。 いちいちまっさらなエンティティーでフォームを表示するのは不親切なので、入力内容はそのままお返しするから必要なところだけ直してね、とする。 初回の処理でリクエストデータがなければ無視されるので安心。
アソシエーションが正しくない
今回の例でいうところの、ユーザーテーブル自体に存在するカラムを編集するinputの場合はいいけど、そのレコードに紐づく別のテーブルのデータを入力する場合。
テーブルクラスでアソシエーションを定義する。
アソシエーションを含めたエンティティーを生成する。
フォームヘルパーに正しく関連レコードを指定する。
という点を確認。
1. テーブルクラスでアソシエーションを定義する。
CakePHPのアソシエーションの概念についてはCakePHP 2のCakebookで丁寧な説明が読める。 http://book.cakephp.org/2.0/ja/models/associations-linking-models-together.html
CakePHP 3での書き方についてはここで。まだ英語版しかないけど、上を読んだ後なら本文飛ばしてサンプルコードだけ読めばOK。 http://book.cakephp.org/3.0/en/orm/associations.html
一点、hasAndBelongsToMany(HABTM) が belongsToMany と呼び名が変わった。端的でいいよね。
深追いすると趣旨がブレるので参考文献の紹介程度にしておく。
2. アソシエーションを含めたエンティティーを生成する。
エンティティー生成の際、関連テーブルもエンティティーに含めたネストされたエンティティーを生成する。
// リクエストデータからユーザーエンティティーを作成 $user = $this->Users->newEntity ( $this->request->data, [ 'contain' => 'Avatars' ]);
こんな感じで、例えばUser has one Avatarなエンティティーを生成。
アバターのさらにその先に別のテーブルを持つ場合はこう。
// リクエストデータからユーザーエンティティーを作成 $user = $this->Users->newEntity ( $this->request->data,[ 'contain' => [ 'Avatars', 'Avatars.Tags' ] ]);
Avatar belongs to many Tagsな想定で。ここはアソシエーションの種類が変わっても特に書き方に差はない。 ちょっとうまいこと架空のアソシエーションが思い浮かばなくてよく分からないサンプルになってるけどお許し。
余談 ちなみに'Avatars.Tags'だけでもちゃんとAvatarsとTagsを含めてくれる。個人的に階段状に書いていくのが整理されていて見やすい。
階段 A A.B A.B.C A.D A.D.E
本当は A.B.C A.D.E だけでも動くけど、Aを2回書いている時点で1回しか書かないことを徹底できないくらいなら最初からやりたくない。
3. フォームヘルパーに正しく関連レコードを指定する。
<?=$this->Form->input('-この部分-')?>
の指定方法。
まず、ユーザーテーブル (createメソッドに渡したエンティティー自体) のカラムの場合、何も工夫せずにカラム名をドン。
<?=$this->Form->input('name')?>
次にhasOneまたはbelongsToなテーブルのカラムの場合。 アソシエートされたエンティティーは、親エンティティーに対して小文字表記のプロパティー名で追加されるので、inputに渡す際もそれに従う。hasOneまたはbelongsToの場合は小文字表記に加えて単数形となる。 (表記はアソシエーション設定時に任意の名称に変更可能。)
<?=$this->Form->input('avatar.title')?>
アバターにタイトルなんかつけるかよ。
次が迷いがち。 hasManyまたはbelongsToManyなテーブルのカラムの場合、複数形の小文字表記に加えて、インデックスを指定してからカラム名をドン。
<?=$this->Form->input('avatar.tags.0.name')?>
アバターに紐づく複数のタグのうち、0番目のレコードのnameカラムですよ、と読む。 アバターにタグなんかつけるかよ。 0番目というのは本当にデータベース全体の話ではなく、今画面上で編集中のレコードのうち0番目。すでにひとつタグがついているアバターに対して、新規に0番目を編集すれば2つのタグができるし、エンティティー生成時にすでにあるタグをfindしてからエンティティーを作った場合は0番目に既存のタグの名前が表示され編集できる。 (その場合はふつうforeachとかで既存のタグ数分ループして複数の入力欄を出すのだろう。)
CakePHPで定数やアプリケーション設定を定義する
PHPのdefineやconstを使用してもいいんだけど、どこに定義する?って問題が出てくる。 どのファイルにっていうのもそうだけど、どの名前空間に?どのクラスに? CakePHPでは定数っぽく使えるConfigの定義と読み込み用のクラスが用意されている。 いや、後から上書きできるから定数ではないんだけどね…。
値を定義する
configディレクトリに定義用のphpファイルを作る。 例 config/constants.php
<?php $config['Code'] = 'ProcessingStatus' => [ 'waiting' => 1, 'progress' => 2, 'finished' => 3 ], 'UserRole' => [ 'admin' => 1, 'editor' => 2, 'auther' => 3, 'subscriber' => 4 ] ];
ネストした定数が定義できる。上記ではCodeという名前でコード値系の定数をまとめている。 以下でも全く同じ。なぜならPHPでは’$未定義の変数[添字] = 値’で自動的に配列が作られるので。
<?php $config['Code']['ProcessingStatus'] = [ 'waiting' => 1, 'progress' => 2, 'finished' => 3 ]; $config['Code']['UserRole'] = [ 'admin' => 1, 'editor' => 2, 'auther' => 3, 'subscriber' => 4 ];
次に作ったファイルを読み込む。拡張子なしでOK。 config/bootstrap.phpで読み込むのがスタンダードなのかな? とりあえす一番下に追加。
config/bootstrap.php
Configure::load('constants');
値を使用する
class宣言の前にuse文でConfigureクラスを読み込む。 (読み込むというよりCakePHPのオートローダーがクラスのファイルを探しに行ってくれる様にしている、だと思う。)
あるコントローラー.php
<?php namespace App\Controller; use Cake\Core\Configure; class ○○Controller extends AppController {
ビューの場合はクラス宣言はしないけど適当に上の方でやる。
あるテンプレート.ctp
<?php use Cake\Core\Configure;?>
参照方法
// ユーザーに管理者権限を設定 $user->set('role', Configure::read('Code.UserRole.admin'));
$userはエンティティーの想定で、これで$user->roleに1がセットされる。 配列のネストを ‘.’ (ドット) 区切りで表現する。 逆にこのケースで、
Configure::read('Code.UserRole')
とした場合、配列
array (size=4) 'admin' => int 1 'editor' => int 2 'auther' => int 3 'subscriber' => int 4
が返される。
PHPでは'$未定義の変数[添字] = 値'で自動的に配列が作られる
CakePHPじゃなくてPHPの話だけど。 何事にもとにかく配列を使用するCakePHPで使えそうなTips。
PHPでは定義されていない変数に対して添字を指定して配列として要素を追加することが許可されている。 ここでは$foo=未定義だが、$foo['bar']への代入を行うと、 暗黙的に$fooという新しい配列が作られ、その配列に対して'bar'という要素が追加される。
$foo['bar'] = 'hoge'; var_dump($foo);
結果
array (size=1) 'bar' => string 'hoge' (length=4)
ネストしていても可能。
$foo['bar']['fuga'] = 'hoge'; var_dump($foo);
結果
array (size=1) 'bar' => array (size=1) 'fuga' => string 'hoge' (length=4)
CakePHPで定数っぽく使用する$configを定義するときに、スマートに書けそう。