将两个语句合并为Ruby中的一个语句

时间:2014-01-16 18:35:38

标签: ruby syntactic-sugar

有没有办法将这个功能变成一个声明?

def test
  err = _invalid_permission
  return err if err # this statement
  # do something else
end

我试过了:

def test
  return (err = _invalid_permission) if err
  # do something else
end

但这有所不同,err始终为ifnil

或者这个:

def test
  return err if (err = _invalid_permission)
  # do something else
end

但是这个导致undefined local variable or method 'err'

我试图做的解释是缩短这种方法:

def test
  err = _invalid_permission
  return err if err
  err = _check_another_error
  return err if err
  err = _and_another_one
  return err if err
  # and lots more
  # do something else when not error
  return nil
end

_invalid_permission_check_another_error_and_another_one将返回包含错误消息的非空字符串或数组或散列。

另一个故事,在看到下面的答案之后,我认为它可以合并到:

def test
  err = _invalid_permission ||
    _check_another_error ||
    _and_another_one
  # and lots more
  return err if err
  # do something else when not error
  return nil
end

5 个答案:

答案 0 :(得分:2)

def test
  (err = _invalid_permission) && return err

  #do something else
end

答案 1 :(得分:2)

你确定你问的是正确的问题吗?您专注于减少必须编写的代码行的一种方法。相反,您需要干掉代码。这是一种方式:

module Checks
  def _invalid_permission() nil end
  def _check_another_error() "oops!" end
  def _and_another_one() nil end
end

class Doit
  @@checks = Checks.instance_methods(false)
  include Checks

  def doit
    @@checks.each { |m| rv = send(m); return rv if rv }

    "test"
  end
end

p Doit.new.doit # => "oops!"

如果你改变了

def _check_another_error() "oops!" end

def _check_another_error() nil end

然后

p Doit.new.doit # => "test"

此方法还允许您添加,删除或重命名检查方法,而无需记住在其他地方更改对它的引用。

答案 2 :(得分:1)

这样可行,但你会牺牲清晰度

def test
  (err = _invalid_permission) ? (return err) : nil
  #do something
end

答案 3 :(得分:1)

def test
  (err = _invalid_permission) or begin
   # do something else
  end
end

答案 4 :(得分:1)

这不会进入组合语句,但如果你要做的是检查一些错误条件,就像你展示的那样,可以通过这样的方式更可读地完成:

def test
  err ||= _invalid_permission
  err ||= _check_another_error
  err ||= _and_another_one
  return err if err
  #do a bunch of other stuff
end

或者,如果你在很多地方这样做,听起来像是一个例外可能有意义。类似的东西:

class MyValidationError < Exception
  attr_accessor :err
  def initialize(err)
    @err = err
  end
end

def check(err_or_nil)
  raise MyValidationError.new(err) if err_or_nil
end

def test
  check _invalid_permission
  check _check_another_error
  check _and_another_one
  #do a bunch of other stuff
rescue MyValidationError
  $!.err
end

但我认为第一个是个人可读的。