В дополнение к данным решениям, если вы знаете, что ивар будет оставаться String / Array / Hash, вы можете сделать следующее:
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' }
Хотя из того, что, я думаю, вы делаетеэто наиболее подходящий код:
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"
Кроме того, вы можете сделать это без блока:
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"
Имейте в виду, что оператор p s
, который вы используете, возвращаетnil
.