貴様らには分かるまい!全角数字の恐ろしさが!
マルチバイトが浸透していない地域では分からないこのめんどくささ。
全角入力→半角数字入力的なフォームがあるとUX的に重要な入力補助。
こんな感じで持っておく。メソッド名が適切じゃないような気がするけど…
String.prototype.toHalfNumber = function() {
return this.replace(/[0123456789]/g, function(a){
var b = "0123456789".indexOf(a);
return (b !== -1) ? b : a;
}).replace(/\d+\.\d+/g, function(a) {
return a.replace(".", ".");
});
};
日本人なら持っておきたいところ←
で、これを
var _number = function(){
var value = $(this).val();
value = value.toHalfNumber().replace(".","");
if(!$.isNumeric(value)) {
$(this).val("");
return;
}
$(this).val(value);
};
とか書いて
$("#foo").on("blur", _number);
として上げるといいんじゃないかと思った。
バリデーションメッセージ出してやるより強制補正かけて上げたほうが地味に使い勝手がよくなった気がする。
その他はここに書いてる
$("input[type=text]").inputSupport();
としてやればHTMLで
<input type="text" data-type="number">
と書いてやっておけば発動する感じ。その他data-type=floatとかdata-type=integerとかdata-type=dateとかも作ったけど。
しかしこれを書いてる途中にはまったテストの部分。
JsTestDriverで
var actual = "0.2".toNumberHalf();
assertString(actual);
assertEquals("0.2", actual);
がコケる。ブラウザ上で実行するとうまくいってる。
ナンデ!ナンデナノ!?
なんか多分マルチバイトなせいで内部的な文字コードでウヴォアってなってるんだろうけど対策方法未発見。
ER図とDB設計とクラス設計について
ちょっと最近スクラッチで作るプロジェクトが始まったのと、TwitterのTLで気になる話題があったので簡略に考えてみる。
まじで簡略に
議題としては、RDBにおいて
- ER図を書く意味って何?
- DB設計を行う優先度
- クラス設計を行う優先度
この3つの事項に対しての意味と、作業の優先順位・着手順といったところ。
DB設計より先にクラス設計を行うべきか
簡単に一概していえない物を一概にして考えをいってみると
クラス設計 > DB設計 となる場合
アプリケーションの役割の比重が低い場合が概ねそうだと思う。
アプリケーションの役割の比重が低いほうが、クラス設計が重要になるというのがちょっと不思議かもしれないけど、スピーディーに開発することが重要で、かつ適切なDB設計を行わなくても問題ないアプリケーション。
例えば、ORマッパーを使用できる(使用して問題ない)アプリケーションの場合はそうだと思う。
つまり、極端に言ってしまえば入れて出すだけのアプリケーションなら大したreadも行わないしそれこそ開発効率を最優先してコードファーストで書いてそれに合わせてDBが作成されてしまえばいい。
オブジェクトを永続化できれば良いのだから。
という考え。
エンティティが完璧に出来上がるならそれでもうほぼ終わりでいいじゃん!みたいな空気になる
そんな状況。
だって正規化って結局DRYの法則に従ってるだけで、クラスをDRYに設計する以上DBもDRYになるし…
DB設計 > クラス設計 となる場合
品質を担保するのが難しいアプリケーション(パフォーマンス面で)
非正規化ガンガンうぇるかも!な状態。むしろ非正規化しないとやってられねーよ、とか、概念モデルや論理モデルが物理モデルを圧倒しちゃうようなアプリケーション。
カーディナリティを考慮せずに設計するなんてアリエナーイ!とか
ORマッパーなんて使用してたらパフォーマンス的にムリゲーとか。
そのほか複数のアプリケーションがそのDBをつついてくる場合(アプリケーションの数だけ役割があるので)
まとめると、クラスの意義でもある「データ」と「操作」をまとめられない時という感じかなぁ…
データと操作は考える上では一緒だけど(だってインデックス設計のときに操作分からないと無理だし…)、システム的な面でデータと操作をまとめてしまうと障害が出てしまうときに。
あとは分散トランザクションなんかが必要な時って、そもそもDBないとクラス設計そのものが面倒になるし(データの設計だけでも終わってくれてれば、その分楽になるし)
あとデッドロック恐怖症の人は迷わずDB設計からどうぞ。
ER図は何のために書くのか
ER図は、概念データモデルが大量にある時や、完全なデータモデルと概念データモデルが表記上大きいギャップを持った時に便利だと思う。
正直営業資料的な要素を除けば、これが大きいんじゃないかなぁと思う。
概念データモデルが、様々な事象によって物理データモデルから算出しにくい時にある必要がある。(多対多のリレーションがめっちゃある時とか)
自分個人としては、概念データモデルも全てクラス化したいからしちゃうし(コンパイルでテストを減らせるから)でも、その概念データモデルが物理データモデルすぐ分からない場合に、その説明的な物で必要だと思う。
正直、DB設計してそれで概念データモデルも大体分かるならER図書いてる暇あればスキーマ作っておいてそれから生成してくれ。という気持ちも強いw
まとめ
トラウマな開発があったせいで偏見に満ち溢れているけど、
クラスで表現しきれる?
○→クラス設計を最優先で行い、その後やっといたほうが良いDB設計なんかと行う
扱う概念モデルが大量にある?
○→ER図をとりあえず書く
データベースの性能をフルで発揮する必要がある? ○→DB設計を最優先で行う
※時間とお金が無制限にある人は除く
CakePHP用のシンタックスエラーをはじくgit hooks
CakePHPを2週間ほど前に始めてさわってやっているけど、まだまだ慣れないので構文だったりで間違ったりする(そもそもPHPが10年ぶりだけど)
のでhooks書いてブロックするようにしてみた。
書いた後に、ねこびーんさんがちゃんと警告出してくれるのと、テストしてからコミットするからいらないんじゃ疑惑が出てきたけどまぁ気にしない
言語はなぜかRuby。(書きやすかったから。shellは長く書くのにどうも慣れないから…)
使いどころとしては、間違ってコミットしちゃうとかそういうののブロック程度にはなると思う。
あとはdiff解決したつもりが出来てないのにコミットする変な人がいた時とか←
軽い修正だからといってテスト通さない人とか…
非推奨メソッドを使用してたら蹴るとかそういうのも書いこう。
まぁそれより問題なのは
アンチPHP過ぎてPHPっぽい物を覚えるのが脳を毒されてる気がしてなかなか覚えられないのと、phpを出来るようになってしまうのが怖い(phpをまたやらなきゃいけなくなるハメになりそうで)
という徹底的にPHPを排除しようとする自分の本能のほう…
CakePHPでバリデーションのヘルパーを作る
phpではstaticなメソッドであってもフィールド内で呼び出しが出来ないためバリデーションのヘルパメソッドを作る場合にはコンストラクタで呼び出すのが良い模様。
動的バリデーションをかけるのと同じ感じで。
例えば
class ValidationHelper {
public static between($min, $max, $option) {
$default = $array('rule' => array('between', $min, $max),
'message' => __('%d文字以上%d字以内', $min, $max));
return array_merge($default, $option);
}
}
みたいな感じにしてコンストラクタ内で
$validate = array(
'field' => array('between' => ValidationHelper::between(5,15))
);
と呼ぶことで一応できるっぽい。 動的バリデーションと同じ感じ
playでカスタムエラーページ
久しぶりにスクラッチで書き始めてみたらカスタムエラーページのやり方を忘れていたのでメモ
公式にも書いてあるけど
GlobalSettingsを継承したGlobalオブジェクトをルートパッケージにつくりそこの
onHandlerNotFoundとか
onErrorをいじる
デフォルトではGlobalオブジェクトは配置されないので迷った。
import play.api._
import play.api.mvc._
import play.api.mvc.Results.__
// デフォルトパッケージに含める
object Global extends GlobalSettings {
override def onHandlerNotFound(request: RequestHeader): Result = NotFound(
views.html.notFoundPage(request.path)
)
}
あとは普通にテンプレート作って404なり500用のページを作っておけばよい。
アノテーションからインスタンス作成
アノテーションからインスタンス作成
NUnitってTestのアノテーションからいろいろ作ってやってるから、リフレクション使えばできるのかなと思い付き、ちょっとやってみた。
やりたいこと
- 実行内容は外界から取ってくる(設定ファイルとかから)
- どこかの名前空間にあるコマンドクラス群を詰め込んである
- 実行の際に、必要に応じてそれらのインスタンスを作成
- けど、コマンドクラス増えるたびにインスタンスを生成・取得するところを修正するのは嫌
ということで、コマンドクラス群にアノテーションを振って、そのアノテーションを元に生成・取得する処理は作ってしまえばインザネと思ったのでちょっとやってみた。
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assem => assem.GetTypes()
.Select(t => t)
.Where(t => t.FullName.Contains("Namespace.Foo"))
.Where(t => Attribute.GetCustomAttributes(t, typeof(BarAttribute)).Length > 0)
.Select(t => t)
);
foreach(Type typ in types)
{
var instance = Activator.CreateInstance(typ);
}
大体こんな感じ
もっとうまいやり方や書き方がある気がするけど、まぁとりあえず良し。
やってることは、Bar属性がついてるクラスをアセンブリ内から探してきて、サンプルのだと、全部インスタンス化してる。
types.Whereとかで、文字列のコマンド名から、インスタンス化する感じ。
連載! とことん C#: 第 16 回 リフレクション (Reflection) を活用する
一応、この辺を参考にしてみた。