2013年10月13日日曜日

[Oracle12c]defaultに指定できるようになったon null句

Oracle12cからは、default区に「on null」が指定できるようになったようだ。
このon nullは、insert文で挿入しようとしている値がnullの場合に、指定した値を挿入してくれます。

※defaultの場合は、insertで指定されていない場合のみ値を挿入してくれるけど、on nullを使用することで完全にnullを除外出来るようになる。
なお、on nullを指定するとnullが入ることがありえないので、not nullを指定しなくても暗黙的にnot nullになる。

create table文

以下のように、defaultの後にon null句を記述し、null時に代入する値を指定する。
create table on_null_test (
  id number not null,
  char_col char(1) default on null '0',    -- nullの場合は、「0」を代入する
  number_col number default on null 100,      -- nullの場合は、「100」を代入する
  primary key (id)
);

insert文を実行

-- 主キー以外は指定しない
INSERT INTO ON_NULL_TEST (id) values (1);
-- nullを代入
INSERT INTO ON_NULL_TEST (id, char_col, number_col) values (2, null, null);
-- null以外を代入
INSERT INTO ON_NULL_TEST (id, char_col, number_col) values (3, '1', 999);

実行結果

IDが1と2の行は、insertで項目を指定していない、nullを指定しているためデフォルトの値が挿入されている。
ID CHAR_COL NUMBER_COL
1 0                 100
2 0                 100
3 1                 999

2013年9月28日土曜日

[coffeescript]typeofよりinstanceof

クラスの型をチェックする場合には、typeofよりinstanceofを使うほうがよい。

下のコード例&実行結果を見るとわかるけど、typeofを使用した場合その変数の型はobjectとなってしまう。
これだと、その変数のクラス型を正しく判定できないのでinstanceofを使用して判定する。

コード例

class Hoge

class Fuga

hoge = new Hoge()
fuga = new Fuga()

console.log typeof hoge             # object
console.log (hoge instanceof Hoge)  # true
console.log (fuga instanceof Hoge)  # false

実行結果

object
true
false

2013年9月15日日曜日

[coffeescript]soak operator(nullを安全に扱えるやつ)

soak operatorというものを使うとnullを安全に扱えるようになる。

hoge = null

console.log hoge
# 値が代入されているかチェック(nullの場合はfalse)
console.log hoge?
# 値が代入されていない場合の初期値を返す
console.log hoge ? 'nullだよ'

# 初期値を代入(?=で値が未設定時の初期値を代入できる)
hoge ?= '初期値'
console.log hoge

# 値が設定されている場合は変わらない
hoge ?= '値は変わらない'
console.log hoge

JavaScriptへの変換結果

JavaScriptへ変換した結果。if文でうまいことnullが考慮されている。
// Generated by CoffeeScript 1.6.3
(function() {
  var hoge;

  hoge = null;

  console.log(hoge);

  console.log(hoge != null);

  console.log(hoge != null ? hoge : 'nullだよ');

  if (hoge == null) {
    hoge = '初期値';
  }

  console.log(hoge);

  if (hoge == null) {
    hoge = '値は変わらない';
  }

  console.log(hoge);

}).call(this);

2013年9月7日土曜日

[coffeescript]可変長引数

JavaScriptの場合、可変長引数みたいなことを実現しようとした場合、関数内でのみ使える配列っぽいargumentsオブジェクトを利用する必要がある。
このargumentsオブジェクトは、配列じゃないのでびみょーに使い勝手が悪かったりするんだよね。

そこで、coffeescriptを使ってあげると関数の引数名に「...」をつけてあげるだけで、いい感じに可変長引数を扱うことができます。

簡単な例を見てみましょう。

可変長引数を1つ受け取る関数

func = (params...) ->
  console.log params.join
  console.log params.join('-')

func 1, 2, 3

上記プログラムの実行結果。パラメータのparamsにはjoin関数が定義されていて、引数で指定した複数の値が、連結されているのがわかります。
[Function: join]
1-2-3

可変長引数とそれ以外の引数を受け取る関数

func = (params..., param2) ->
  console.log params.length
  console.log params.join('-')
  console.log "param2 = [#{param2}]"

func 1, 2, 3

上記プログラムを実行すると、最後に指定したパラメータが2番めの引数に、最後を除くパラメータが可変長引数に設定されていることがわかります。
2
1-2
param2 = [3]


コンパイルされたJavaScriptを見てみると

可変長引数を、配列のslice関数を使用して配列に変換しているようです。
(function() {
  var func,
    __slice = [].slice;

  func = function() {
    var params;
    params = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
    console.log(params.join);
    return console.log(params.join('-'));
  };

}).call(this);

2013年8月31日土曜日

[coffeescript]ビルトインオブジェクトを拡張

coffeescriptでビルトインオブジェクトのDateの拡張に挑戦。

format関数を追加して、Date#formatで年月日フォーマットした値を返すようにしてみた。

[CoffeeScript]prototypeへの簡易アクセスで書いたように、「::」でプロトタイプにアクセスできるので、「::」に対して追加したい関数を定義してあげれば良い

Date::format = ->
  "#{@.getFullYear()}年#{@.getMonth() + 1}月#{@.getDate()}日"

console.log new Date().format()

実行結果
2013年8月31日

2013年8月17日土曜日

[CoffeeScript]prototypeへの簡易アクセス

CoffeeScriptでも、JavaScriptと同じよに「Hoge.prototype」とするとプロトタイプにアクセスすることができます。
CoffeeScriptでは、prototypeへのアクセスを更に簡単に記述出来るように、クラス名::とコロン(:)を2つ連続して書くことでプロトタイプにアクセスできます。

# クラス宣言
class Hoge
  hoge : -> "hoge"

# プロトタイプに関数を追加
Hoge::func = -> "func"

# プロトタイプの内容を出力
console.log Hoge::

# 上記分は、以下の文と同じ
console.log Hoge.prototype

上記分を実行すると、「::」でプロトタイプにアクセスできている事がわかります。
/usr/local/bin/coffee example.coffee
{ hoge: [Function], func: [Function] }
{ hoge: [Function], func: [Function] }

2013年8月3日土曜日

[CoffeeScript]メソッドのオーバライド

継承した親クラスと同名のメソッドを小クラス側に定義することで、親クラスの処理を上書きできる。
親クラスの処理を呼び出したい場合には、superで実現できる。引数がある場合には、superにパラメータとして指定すれば良い。

class Super

  func: ->
    console.log 'Super#func'


class Sub extends Super
  func: ->
    console.log 'sub#func'
    super


sub = new Sub()
sub.func()
上記コードを実行すると、以下のようにsuperキーワードで親クラスの同一メソッドが呼び出せていることが確認できる。
sub#func
Super#func