色々なオブジェクトの存在確認をしたい
人様の書いたコードを読むにつけ、hoge.nil?
だとか、if params[:hoge]
、hoge.blank?
だとかif foo.hoge.size==0
だとか、色々な書き方を見て、何をどう使えばいいのかわからなくなってきたrails(ruby)初心者です。
前回の記事を書いていて、少しだけわかったような気になったのですが、細かい仕様の違いにまだ慣れておらず。
自分用の備忘録と、メタプログラミングの基礎練習がてらに実験してみました。
というわけで結果
こんな感じになりました。
@undefined
は定義されていないインスタンス変数(適当な名前)です。
本当に未定義の変数(を意図した文字列)を突っ込むと、rubyがメソッドか変数かも解釈できず、実行不能になるので@をつけました。!
は、論理評価をさせるために入れました。よく、if hoge
だとか、unless hoge
というコードがありますが、そういう形での評価に対応しています。
雑感など
未定義かもしれない変数を確認する時は、少なくともそれが変数であることをrubyがわかってさえいれば、いろいろ確認手段はある。(rubyが変数かどうかすら判断できないような名前だと、どうすればいいのでしょう・・)
未定義(初期化されていない)インスタンス変数(つまり@hogehogeのようなもの)への参照はnilを返す。つまり結果的にはnilに対する評価と同じ結果になる。当然ながら、インスタンス変数が定義(初期化)されている場合は、変数の中身に応じて挙動が変わる。
'nil?'と'!'の振る舞いは
false
への反応を除いて同じ(前回調査済み)blank?
とpersent?
は表裏の関係(お互いの論理否定)count/size/lengthは予想以上にまちまち。
0.size = 8
というのは、Integer型のバイト数。
たとえば(1000**10).size
とかやってみると、数字が増えていくのが確認できます。
コードなど
ちょこちょこっとrailsで出力してみたレベルですが参考になれば・・。
class NiltestController < ApplicationController
def index
method_test
end
private
def method_test
test_methods = [
'nil?',
'!',
'empty?',
'blank?',
'present?',
'count',
'size',
'length',
'any?',
'zero?'
]
test_objects = {
'@undefined' => @undefined,
'nil' => nil,
'false' => false,
'true' => true,
'""' => "",
'" "' => " ",
'"hoge"' => "hoge",
'[]' => [],
'[@undefined]' => [@undefined],
'[nil]' => [nil],
'{}' => {},
'{hoge: @undefined}' => {hoge: @undefined},
'{hoge: nil}' => {hoge: nil},
'0' => 0,
'0.0' => 0.0,
'"0"' => "0"
}
@methods = test_methods
@results = []
test_objects.each do |label, obj|
res = [label]
test_methods.each do |meth|
begin
res << (obj.send meth).to_s
rescue => e
res << e.class.to_s
end
end
@results << res
end
end
end
<div class='container'>
<table class='table table-striped'>
<tr>
<th>methods</th>
<% @methods.each do |obj| %>
<th><%= obj %></th>
<% end %>
</tr>
<% @results.each do |res| %>
<tr>
<% res.each do |r| %>
<td><%= r %></td>
<% end %>
</tr>
<% end %>
</table>
</div>
環境
ruby 2.3.0p0
Rails 4.2.7.1
です。(rails5じゃなくてすみません・・)
参考サイト
例によって様々なサイトを参考にさせていただきましたが、特に下記のサイトでの確認方法を盛大に参考にさせていただきました。この場を借りて感謝させてください。