Reputation: 43
Hi!
I am expecting #<PrettyThing:0x0055a958175348 @success="anything here">
but I am getting 'anything here'
instead. Any idea why?
class Thing
attr_accessor :success
def execute
self.success = execute!
rescue
self.success = false
ensure
self
end
end
class PrettyThing < Thing
def execute!
'anything here'
end
end
p PrettyThing.new.execute # => 'anything here'
Upvotes: 1
Views: 888
Reputation: 20263
Try:
class Thing
attr_accessor :success
def execute
self.success = execute!
self
rescue
self.success = false
end
end
class PrettyThing < Thing
def execute!
'anything here'
end
end
p PrettyThing.new.execute # => <PrettyThing:0x0000000379ea48 @success="anything here">
The way you have it written, execute
is returning the assignment result of self.success = execute!
. By adding self
, you return the instance of PrettyThing
.
This is handy if you want to chain methods, like:
class Thing
attr_accessor :success
def execute
self.success = execute!
self
rescue
self.success = false
end
def foo
puts 'foo'
end
end
class PrettyThing < Thing
def execute!
'anything here'
end
end
p PrettyThing.new.execute.foo # => foo
Given your comment, I think I'd probably do it something more like:
class Thing
attr_accessor :success
alias success? success
def foo
puts 'foo'
end
end
class PrettyThing < Thing
def execute
@success = everything_worked
self
end
private
def everything_worked
# your logic goes here
# return true if all is good
# return false or nil if all is not good
true
end
end
pretty_thing = PrettyThing.new.execute
p pretty_thing.success? # => true
If everything_worked
returns false
or nil
, then pretty_thing.success?
will also return false
or nil
.
Upvotes: 3
Reputation: 3230
Ensure is a tricky thing. Normally, it doesn't return a value, and instead the return value from the last executed line of the main or rescue block is returned, unless there was an uncaught error, then the error is returned. But, if you explicitly return, then you will get the return value. This is a bit nonstandard and confusing though, because the intent of the ensure
clause is for silent cleanup. It may be better to move your return value outside your begin
/rescue
block.
Upvotes: 3