基本的Ruby。为什么此方法返回nil?

时间:2018-07-06 00:39:50

标签: ruby-on-rails ruby

嗨!

我期望#<PrettyThing:0x0055a958175348 @success="anything here">

但是我却得到'anything here'。知道为什么吗?

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'

2 个答案:

答案 0 :(得分:3)

确保是一件棘手的事情。通常,它不返回值,而是返回主块或救援块最后执行的行的返回值,除非存在未捕获的错误,否则将返回错误。但是,如果您显式返回,则将获得返回值。但是,这有点不规范且令人困惑,因为ensure子句的目的是用于静默清除。最好将返回值移到begin / rescue块之外。

答案 1 :(得分:3)

尝试:

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">

execute的编写方式将返回self.success = execute!的赋值结果。通过添加self,您将返回PrettyThing的实例。

如果要链接方法,例如:

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

鉴于您的评论,我想我可能会更喜欢:

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

如果everything_worked返回falsenil,则pretty_thing.success?也将返回falsenil