Ktouth Brand. on Web

け〜くんこと K.Ktouth のだらだらした日常と突発的に作るプログラムや読み物とかの雑多サイト



[2010年03月28日]

小一時間悩んだ

2010年03月29日 07:00更新 筆者:K.Ktouth

たのしいRuby 第3版(AA)

日記データのコンバータを作成中に1時間は悩んだアホなコードミス。

def push_item(item); (@items ||= []).push item end

上記コードの括弧内の部分は良くあるシンタックスシュガーという奴。
インスタンス変数の初期化をコンストラクタなどで行わずに、初めて参照するタイミングで初期化したい際に使う良くある手法です。
で、以下が今回のコードミス。

def no_rewrite?; @is_no_rewrite ||= true end
def set_no_rewrite; @is_no_rewrite = false end

一見、なんの問題もないように見えるこのコード。
しかし実行してみるとわかるのですがなんど #set_no_rewrite を実行しても #no_rewrite? は true しか返さないのです。
このシンタックスシュガーは「未定義は真偽判定で false と同じ扱いをされる」というのを利用しているわけですが、それは逆に言うと「値として false を取り得る、初期値が true の変数の初期化には使えない」と言うことです。
今回の場合はもっときっちりと書く必要があったというわけです。
最終的にはこういうコードになりました。

def no_rewrite?
 defined?(@is_no_rewrite) ? @is_no_rewrite : true
end
def set_no_rewrite; @is_no_rewrite = false end

無精してはいけない、と言うことですね(ぉぃ

本日のリンク元
アンテナ
その他のリンク元
検索