In addition to the given solutions, if you know the ivar is going to stay String/Array/Hash, whatever, you could do the following:
class Topic
def subject
@subject ||= 'sane default'
if block_given? then yield(@subject)
else @subject
end
end
end
t = Topic.new
t.subject { |s| s.replace 'fancy stuff' }
Though from what I guess you are doing, this is the most appropriate code:
class Topic
def subject
return @subject unless block_given?
@subject = yield(@subject)
end
end
t = Topic.new
t.subject { |s| 'fancy stuff' }
t.subject { |s| "very #{s}" }
t.subject # => "very fancy stuff"
Also, you could actually do that without a block:
class Topic
def subject(value = nil)
@subject = value % @subject if value
@subject = yield @subject if block_given?
@subject
end
end
t = Topic.new
t.subject 'fancy stuff' # => "fancy stuff"
t.subject 'very %s' # => "very fancy stuff"
t.subject { |s| s.sub 'fancy', 'freaky' } # => "very freaky stuff"
Keep in mind that the statement p s
you are using returns nil
.