Hatena::Diary

予定は未定Blog版 このページをアンテナに追加 RSSフィード

カレンダー
<< 2010/02 >>
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
あわせて読みたい
 

2010-02-07

[]言わなかったこと・発表資料だけではわからないこと

昨日のわんくまで言わなかったこと、発表資料だけではわからないことです。

ちなみに発表資料はこちら→わんくま 名古屋勉強会 #11 の発表用資料 - 予定は未定Blog版

続きを読む

[][]TestCase 属性などによるテストコードのリファクタリング

昨日のわんくまの昼休みに TDD 道場があったんですが、テストコードのリファクタリングについて賛否あったのでちょっと自分の考えをまとめておきます。

それに加え、C# と NUnit でどのようにテストコードをリファクタリングできるか、というのも紹介します。

というかこちらがメイン。


テストを追加した際に追加したテストだけを実行するか全部実行するかというのも意見が分かれたんですが、主に個別に指定するのが面倒という理由で全部実行する派です。

全部実行すると時間がかかる?それはもはや単体テストじゃないですね。重いテストは分割して分離しちゃいましょう。

これに関してはレガシーコード改善ガイド (Object Oriented SELECTION)をどうぞ。機会があればここら辺についても書きたいところです。

続きを読む

2010-02-06

[]わんくま 名古屋勉強会 #11 の発表用資料

発表用資料

Git でどういうことができるのかの紹介です。

まだ Git を使ったことが無い人・使いはじめの人を対象としています。たぶん。


こちらもあわせてどうぞ:言わなかったこと・発表資料だけではわからないこと - 予定は未定Blog版

2010-02-01

[]SQL (再帰 CTE) 基礎文法 (?) 最速マスター

なんか流行ってるらしいので。

他の言語をある程度知っている人はこれを読めば SQL (再帰 CTE) の基礎をマスターして SQL (再帰 CTE) を書くことができるようになります。

・・・嘘ですごめんなさい。

ぜんてい

いつもの通り、SQL Server 2005/2008 でしか試してないよ!

基礎

コメント

コメントは 2 とおり

-- 一行コメント
/*
複数行
コメント
 */
基本形
-- 1から10までの数字を表示するSQL
WITH
  -- 入力は1から10まで
  Input(f, t) AS (
    SELECT 1, 10
  )
, Seq(n) AS (
    -- 最初はInputのf
    SELECT f FROM Input
    UNION ALL
    -- それ以降は1ずつ数値をインクリメント
    SELECT
        n + 1
    FROM
        Seq
    WHERE
        -- n + 1がInputのtより小さい間出力
        n + 1 <= (SELECT t FROM Input)
  )
-- 出力
SELECT
    n
FROM
    Seq
ORDER BY
    n
;

このように、WITH Input・・・処理 (UNION ALL を使用した共通表式)・・・出力 (最終的な SELECT) の形をとります。

また、いろいろと変形が考えられ、たとえば

WITH
  Input(f, t) AS (
    SELECT 1, 10
  )
, Seq(n) AS (
    SELECT f FROM Input
    UNION ALL
    SELECT
        n + 1
    FROM
        Seq
          INNER JOIN Input ON Seq.n + 1 <= Input.t
  )
SELECT
    n
FROM
    Seq
ORDER BY
    n
;

とも記述できます。

変数の定義

変数は以下のように定義します。

変数のグループ名(変数名1, 変数名2, ...) AS (
  SELECT 変数名1の値, 変数名2の値 ...
)

Input も変数ということになります。

また、変数は定義した場所以降でどこでも使えますが、値を変更することはできません。

数値

整数も実数も使えます。

SELECT 10, 0.5
四則演算
SELECT 1 + 1
SELECT 1 - 1
SELECT 1 * 2
SELECT 5 / 2
SELECT 5.0 / 2
SELECT 5 % 2
インクリメント・デクリメント

ありません。

文字列

文字列はシングルクォートで囲みます。

プレフィックスとして N を付けると Unicode 定数になります。

SELECT 'abc'
SELECT N'abc'
文字列操作
-- 結合
SELECT 'aaa' + 'bbb' -- aaabbb
-- 分割・・・後で
-- 長さ
SELECT LEN('abcdef') -- 6
-- 切り出し
SELECT SUBSTRING('abcd', 1, 3) -- abc
-- 検索
SELECT CHARINDEX('bc', 'abcd') -- 2

分割を行う関数は無いし何返せばいいのか分からないので CTE で代用します。

WITH
  Input(s, delim) AS (
    SELECT 'aaa,bbb,ccc', ','
  )
, SplitCore(i, res, delim, s) AS (
    SELECT 0, CAST(NULL AS varchar(max)), delim, s FROM Input
    UNION ALL
    SELECT
        i + 1
      , CAST(COALESCE(LEFT(s, NULLIF(CHARINDEX(delim, s), 0) - 1), s) AS varchar(max))
      , delim
      , SUBSTRING(s, NULLIF(CHARINDEX(delim, s), 0) + 1, LEN(s))
    FROM
        SplitCore
    WHERE
        s IS NOT NULL
  )
, Split(i, res) AS (
    SELECT i, res FROM SplitCore WHERE res IS NOT NULL
  )
SELECT
    res
FROM
    Split
ORDER BY
    i

配列

配列を使いたくなったら SELECT で代用しましょう。

WITH
  Array(i, val) AS (
    SELECT 0, 100
    UNION ALL
    SELECT 1, 200
    UNION ALL
    SELECT 2, 300
  )
SELECT i, val FROM Array
UNION ALL
-- 要素の個数
SELECT COUNT(*), NULL FROM Array
-- ここらへん一体何に使うんでしょうね?わかりません
WITH
  Array(i, val) AS (
    SELECT 0, 1
    UNION ALL
    SELECT 1, 2
    UNION ALL
    SELECT 2, 3
  )
-- 先頭を取り出す
SELECT TOP 1 * FROM Array
UNION ALL
-- 末尾を取り出す
SELECT i, val FROM Array WHERE i = (SELECT MAX(i) FROM Array)
UNION ALL
-- 末尾に追加
SELECT i, val FROM Array
UNION ALL
SELECT MAX(i) + 1, 9 FROM Array

制御文

文は全体で一文なので、制御文はないです。

制御式

分岐

分岐には CASE 式を使用します。

-- 単純CASE式
CASE col
WHEN 'a' THEN 0
WHEN 'b' THEN 10
         ELSE -1
END

--検索CASE式
CASE
WHEN col = 'a'
  THEN 0
WHEN col IN('b', 'c')
  THEN 10
  ELSE -1
END
繰り返し

繰り返しには再帰 CTE を使います。

パターンとしてはいくつもありますが、文字列の分割で示した入力をループごとに減らしていく方法の他に、添え字を使用することもできます。

WITH
  -- 入力に添え字を追加する
  Input(i, s) AS (
    SELECT 0, 'aaa'
    UNION ALL
    SELECT 1, 'bbb'
    UNION ALL
    SELECT 2, 'ccc'
  )
, MaxIdx(i) AS (
    SELECT MAX(i) FROM Input
  )
, StrJoin(s, i) AS (
    SELECT
        CAST(s AS varchar(max))
      , i
    FROM
        Input
    WHERE
        i = 0
    UNION ALL
    SELECT
        CAST(S.s + I.s AS varchar(max))
        -- 添え字を増やしていく(場合によっては減らしていく)
      , S.i + 1
    FROM
        StrJoin S
          INNER JOIN Input I ON S.i + 1 = I.i
    WHERE
        -- 添え字で終了を判断
        S.i <> (SELECT i FROM MaxIdx)
  )
, Result(s) AS (
    SELECT s FROM StrJoin
    WHERE i = (SELECT i FROM MaxIdx)
  )
SELECT * FROM Result

サブルーチン・メソッド

ありません。

ファイル入出力

できません。

知っておいた方がいい○○

って何かありますかね?

え?再帰 CTE なんて使わない?ハハハ、そんなバカな。


追記:

ありました!ありましたよ知っておいた方がいい○○!

再帰の上限を設定する

再帰の上限を設定し、それ以上再帰されるとエラーになります。

WITH
  Seq(n) AS (
    SELECT 1
    UNION ALL
    SELECT
        n + 1
    FROM
        Seq
    WHERE
        n < 150
  )
SELECT * FROM Seq
OPTION (MAXRECURSION 200)

最後の OPTION (MAXRECURSION 200) というのがそれです。

何も指定しないと 100 を指定したときと変わらないので、OPTION 部分をはずすと実行時にエラーになります。


また、0 を指定すると無制限になります。最強ですね。

再帰の上限がなくなった SQL にもはや敵など存在しないも同然です。

どれくらい最強なの?

Brainf*ck とか実装できます

ほかにも、BrainCrash なんてものももちろん実装できます

でも一番最強だと思ったのは、電卓ですかね。

2010-01-18

[]+ とか -

昨日のエントリの「演算子に対応する名前」で + や - に対応する名前は Add や Subtract よりも Plus や Minus の方がいいと書いたけど、Scala ではどうなってるのか試してみた。

scala> def +-(){}
$plus$minus: ()Unit

おぉ、plus と minus になってますね!

・・・まぁ Scala は operator + の多重定義というか、そもそもメソッド名に + とか普通に使えて、ただ単に記号としてマッピングしてるから add じゃなくて plus ってつけてる、と言えなくもないけど。

なんで、

scala> def !(){}
$bang: ()Unit

だしね。

2010-01-17

[][].NET のクラスライブラリ設計

とっくに読み終わっていたんだけど、まとめる時間がなかったのでかなり時間が空いてしまった・・・

ということで基本的には「・・・ん?」って思ったところとかのまとめです。

続きを読む

2010-01-08

[]アサーションのメッセージ用文字列をいい感じに組み立てる

アサーションに引っかかったときに出すメッセージの構築って面倒ですよね。

Java はアサーションが文法に組み込まれているくせに、アサーションの評価に使った式を表示してくれもしないという・・・

でも C# は文法にさえ組み込まれていないのでもっとアレ・・・

いやいや、C# には式木というものがあるのですよ。

これを使ってメッセージ用の文字列をいい感じに組み立てるアサーション用のメソッドを作ってみました。まだ途中だけど。


以下コードが微妙に長いので注意。

続きを読む

2009-12-23

[][]msysgit で日本語ファイル名を扱えるようにする (途中)

msysgit で日本語ファイル名を含むリポジトリの clone を作ると、文字化けしちゃうことがあります。

とりあえず試したのは、

clone 元結果
別 PC の Cygwin 版 Git文字化け
同一 PC の msysgit文字化けしない

と、こんな感じです。

他のパターンを試した方は是非教えてください。


で、このままではイヤなので、日本語ファイル名が扱えるように msysgit に手を入れてみました*1

ただ、まだ途中なので、もっと良い方法がある!とか、完全版にしてやんよ!って人がいたら是非!

続きを読む

*1:Bazaar 使え?いや、Git が使いたいんです!

 
この日記のはてなブックマーク数