Should I use if defined?
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find
Or ||=
@current_user_session ||= UserSession.find
I noticed the if defined?
method being used more and more recently. Is there any advantage to one over the other? Personally, I prefer ||=
for readability. I also think Rails might have a memoize
macro which provides this behavior transparently. Is this the case?
Be careful: x ||= y assigns x = y if x returns false. That may mean that x is undefined, nil, or false.
There are many times variables will be defined and false, though perhaps not in the context of the @current_user_session instance variable.
If you desire conciseness, try the conditional construct:
defined?(@current_user_session) ?
@current_user_session : @current_user_session = UserSession.find
or just:
defined?(@current_user_session) || @current_user_session = UserSession.find
if you just need to initialize the variable.
Rails does have memoization, check out the screencast below for a great introduction:
http://railscasts.com/episodes/137-memoization
class Product < ActiveRecord::Base
extend ActiveSupport::Memoizable
belongs_to :category
def filesize(num = 1)
# some expensive operation
sleep 2
12345789 * num
end
memoize :filesize
end
Additionally, the nicer ||=
produces a warning (on 1.8.6 and 1.8.7, at least) about uninitialized instance variables, while the more verbose defined?
version does not.
On the other hand, this probably does what you want:
def initialize
@foo = nil
end
def foo
@foo ||= some_long_calculation_for_a_foo
end
But this almost certainly does not:
def initialize
@foo = nil
end
def foo
return @foo if defined?(@foo)
@foo = some_long_calculation_for_a_foo
end
since @foo
will always be defined at that point.